zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/md5/asm/md5-586.pl b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/asm/md5-586.pl
new file mode 100644
index 0000000..7986a24
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/asm/md5-586.pl
@@ -0,0 +1,318 @@
+#! /usr/bin/env perl
+# Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with 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]);
+
+$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 or die "error closing 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");
+
+	# &not($tmp1)
+	&xor($tmp1,$d) if $pos < 0; 	# I function - part 2
+
+	&or($tmp1,$b);				# I function - part 3
+	&lea($a,&DWP($t,$a,$tmp2,1));
+
+	&xor($tmp1,$c); 			# I function - part 4
+	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0))	if $pos != 2; # load X/k value
+	&mov($tmp2,&wparam(0)) if $pos == 2;
+
+	&add($a,$tmp1);
+	&mov($tmp1,-1) if $pos < 1;	# H function - part 1
+	&add($K,64) if $pos >=1 && !$normal;
+
+	&rotl($a,$s);
+
+	&xor($tmp1,&Np($d)) if $pos <= 0; 	# I function - part = first time
+	&mov($tmp1,&DWP( 0,$tmp2,"",0)) if $pos > 0;
+	&add($a,$b);
+	}
+
+
+sub md5_block
+	{
+	local($name)=@_;
+
+	&function_begin_B($name,"",3);
+
+	# parameter 1 is the MD5_CTX structure.
+	# A	0
+	# B	4
+	# C	8
+	# D 	12
+
+	&push("esi");
+	 &push("edi");
+	&mov($tmp1,	&wparam(0)); # edi
+	 &mov($X,	&wparam(1)); # esi
+	&mov($C,	&wparam(2));
+	 &push("ebp");
+	&shl($C,	6);
+	&push("ebx");
+	 &add($C,	$X); # offset we end at
+	&sub($C,	64);
+	 &mov($A,	&DWP( 0,$tmp1,"",0));
+	&push($C);	# Put on the TOS
+	 &mov($B,	&DWP( 4,$tmp1,"",0));
+	&mov($C,	&DWP( 8,$tmp1,"",0));
+	 &mov($D,	&DWP(12,$tmp1,"",0));
+
+	&set_label("start") unless $normal;
+	&comment("");
+	&comment("R0 section");
+
+	&R0(-2,$A,$B,$C,$D,$X, 0, 7,0xd76aa478);
+	&R0( 0,$D,$A,$B,$C,$X, 1,12,0xe8c7b756);
+	&R0( 0,$C,$D,$A,$B,$X, 2,17,0x242070db);
+	&R0( 0,$B,$C,$D,$A,$X, 3,22,0xc1bdceee);
+	&R0( 0,$A,$B,$C,$D,$X, 4, 7,0xf57c0faf);
+	&R0( 0,$D,$A,$B,$C,$X, 5,12,0x4787c62a);
+	&R0( 0,$C,$D,$A,$B,$X, 6,17,0xa8304613);
+	&R0( 0,$B,$C,$D,$A,$X, 7,22,0xfd469501);
+	&R0( 0,$A,$B,$C,$D,$X, 8, 7,0x698098d8);
+	&R0( 0,$D,$A,$B,$C,$X, 9,12,0x8b44f7af);
+	&R0( 0,$C,$D,$A,$B,$X,10,17,0xffff5bb1);
+	&R0( 0,$B,$C,$D,$A,$X,11,22,0x895cd7be);
+	&R0( 0,$A,$B,$C,$D,$X,12, 7,0x6b901122);
+	&R0( 0,$D,$A,$B,$C,$X,13,12,0xfd987193);
+	&R0( 0,$C,$D,$A,$B,$X,14,17,0xa679438e);
+	&R0( 1,$B,$C,$D,$A,$X,15,22,0x49b40821);
+
+	&comment("");
+	&comment("R1 section");
+	&R1(-1,$A,$B,$C,$D,$X,16, 5,0xf61e2562);
+	&R1( 0,$D,$A,$B,$C,$X,17, 9,0xc040b340);
+	&R1( 0,$C,$D,$A,$B,$X,18,14,0x265e5a51);
+	&R1( 0,$B,$C,$D,$A,$X,19,20,0xe9b6c7aa);
+	&R1( 0,$A,$B,$C,$D,$X,20, 5,0xd62f105d);
+	&R1( 0,$D,$A,$B,$C,$X,21, 9,0x02441453);
+	&R1( 0,$C,$D,$A,$B,$X,22,14,0xd8a1e681);
+	&R1( 0,$B,$C,$D,$A,$X,23,20,0xe7d3fbc8);
+	&R1( 0,$A,$B,$C,$D,$X,24, 5,0x21e1cde6);
+	&R1( 0,$D,$A,$B,$C,$X,25, 9,0xc33707d6);
+	&R1( 0,$C,$D,$A,$B,$X,26,14,0xf4d50d87);
+	&R1( 0,$B,$C,$D,$A,$X,27,20,0x455a14ed);
+	&R1( 0,$A,$B,$C,$D,$X,28, 5,0xa9e3e905);
+	&R1( 0,$D,$A,$B,$C,$X,29, 9,0xfcefa3f8);
+	&R1( 0,$C,$D,$A,$B,$X,30,14,0x676f02d9);
+	&R1( 1,$B,$C,$D,$A,$X,31,20,0x8d2a4c8a);
+
+	&comment("");
+	&comment("R2 section");
+	&R2( 0,-1,$A,$B,$C,$D,$X,32, 4,0xfffa3942);
+	&R2( 1, 0,$D,$A,$B,$C,$X,33,11,0x8771f681);
+	&R2( 2, 0,$C,$D,$A,$B,$X,34,16,0x6d9d6122);
+	&R2( 3, 0,$B,$C,$D,$A,$X,35,23,0xfde5380c);
+	&R2( 4, 0,$A,$B,$C,$D,$X,36, 4,0xa4beea44);
+	&R2( 5, 0,$D,$A,$B,$C,$X,37,11,0x4bdecfa9);
+	&R2( 6, 0,$C,$D,$A,$B,$X,38,16,0xf6bb4b60);
+	&R2( 7, 0,$B,$C,$D,$A,$X,39,23,0xbebfbc70);
+	&R2( 8, 0,$A,$B,$C,$D,$X,40, 4,0x289b7ec6);
+	&R2( 9, 0,$D,$A,$B,$C,$X,41,11,0xeaa127fa);
+	&R2(10, 0,$C,$D,$A,$B,$X,42,16,0xd4ef3085);
+	&R2(11, 0,$B,$C,$D,$A,$X,43,23,0x04881d05);
+	&R2(12, 0,$A,$B,$C,$D,$X,44, 4,0xd9d4d039);
+	&R2(13, 0,$D,$A,$B,$C,$X,45,11,0xe6db99e5);
+	&R2(14, 0,$C,$D,$A,$B,$X,46,16,0x1fa27cf8);
+	&R2(15, 1,$B,$C,$D,$A,$X,47,23,0xc4ac5665);
+
+	&comment("");
+	&comment("R3 section");
+	&R3(-1,$A,$B,$C,$D,$X,48, 6,0xf4292244);
+	&R3( 0,$D,$A,$B,$C,$X,49,10,0x432aff97);
+	&R3( 0,$C,$D,$A,$B,$X,50,15,0xab9423a7);
+	&R3( 0,$B,$C,$D,$A,$X,51,21,0xfc93a039);
+	&R3( 0,$A,$B,$C,$D,$X,52, 6,0x655b59c3);
+	&R3( 0,$D,$A,$B,$C,$X,53,10,0x8f0ccc92);
+	&R3( 0,$C,$D,$A,$B,$X,54,15,0xffeff47d);
+	&R3( 0,$B,$C,$D,$A,$X,55,21,0x85845dd1);
+	&R3( 0,$A,$B,$C,$D,$X,56, 6,0x6fa87e4f);
+	&R3( 0,$D,$A,$B,$C,$X,57,10,0xfe2ce6e0);
+	&R3( 0,$C,$D,$A,$B,$X,58,15,0xa3014314);
+	&R3( 0,$B,$C,$D,$A,$X,59,21,0x4e0811a1);
+	&R3( 0,$A,$B,$C,$D,$X,60, 6,0xf7537e82);
+	&R3( 0,$D,$A,$B,$C,$X,61,10,0xbd3af235);
+	&R3( 0,$C,$D,$A,$B,$X,62,15,0x2ad7d2bb);
+	&R3( 2,$B,$C,$D,$A,$X,63,21,0xeb86d391);
+
+	# &mov($tmp2,&wparam(0));	# done in the last R3
+	# &mov($tmp1,	&DWP( 0,$tmp2,"",0)); # done is the last R3
+
+	&add($A,$tmp1);
+	 &mov($tmp1,	&DWP( 4,$tmp2,"",0));
+
+	&add($B,$tmp1);
+	&mov($tmp1,	&DWP( 8,$tmp2,"",0));
+
+	&add($C,$tmp1);
+	&mov($tmp1,	&DWP(12,$tmp2,"",0));
+
+	&add($D,$tmp1);
+	&mov(&DWP( 0,$tmp2,"",0),$A);
+
+	&mov(&DWP( 4,$tmp2,"",0),$B);
+	&mov($tmp1,&swtmp(0)) unless $normal;
+
+	&mov(&DWP( 8,$tmp2,"",0),$C);
+	 &mov(&DWP(12,$tmp2,"",0),$D);
+
+	&cmp($tmp1,$X) unless $normal;			# check count
+	 &jae(&label("start")) unless $normal;
+
+	&pop("eax"); # pop the temp variable off the stack
+	 &pop("ebx");
+	&pop("ebp");
+	 &pop("edi");
+	&pop("esi");
+	 &ret();
+	&function_end_B($name);
+	}
+
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/md5/asm/md5-sparcv9.pl b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/asm/md5-sparcv9.pl
new file mode 100644
index 0000000..3595e3d
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/asm/md5-sparcv9.pl
@@ -0,0 +1,437 @@
+#! /usr/bin/env perl
+# Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with 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 <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+#
+# 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 <appro\@openssl.org>"
+.align	4
+___
+
+# Purpose of these subroutines is to explicitly encode VIS instructions,
+# so that one can compile the module without having to specify VIS
+# 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 or die "error closing STDOUT: $!";
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/md5/asm/md5-x86_64.pl b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/asm/md5-x86_64.pl
new file mode 100755
index 0000000..c6a172d
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/asm/md5-x86_64.pl
@@ -0,0 +1,393 @@
+#! /usr/bin/env perl
+# Author: Marc Bevand <bevand_m (at) epita.fr>
+# Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with 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 .= <<EOF;
+	xor	$y,		%r11d		/* y ^ ... */
+	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
+	and	$x,		%r11d		/* x & ... */
+	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
+	xor	$z,		%r11d		/* z ^ ... */
+	add	%r11d,		$dst		/* dst += ... */
+	rol	\$$s,		$dst		/* dst <<< s */
+	mov	$y,		%r11d		/* (NEXT STEP) z' = $y */
+	add	$x,		$dst		/* dst += x */
+EOF
+}
+
+# round2_step() does:
+#   dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s)
+#   %r10d = X[k_next]
+#   %r11d = z' (copy of z for the next step)
+#   %r12d = z' (copy of z for the next step)
+# Each round2_step() takes about 5.4 clocks (11 instructions, 2.0 IPC)
+sub round2_step
+{
+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+    $code .= " mov	%edx,		%r11d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
+    $code .= " mov	%edx,		%r12d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
+    $code .= <<EOF;
+	not	%r11d				/* not z */
+	and	$x,		%r12d		/* x & z */
+	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
+	and	$y,		%r11d		/* y & (not z) */
+	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
+	or	%r11d,		%r12d		/* (y & (not z)) | (x & z) */
+	mov	$y,		%r11d		/* (NEXT STEP) z' = $y */
+	add	%r12d,		$dst		/* dst += ... */
+	mov	$y,		%r12d		/* (NEXT STEP) z' = $y */
+	rol	\$$s,		$dst		/* dst <<< s */
+	add	$x,		$dst		/* dst += x */
+EOF
+}
+
+# round3_step() does:
+#   dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s)
+#   %r10d = X[k_next]
+#   %r11d = y' (copy of y for the next step)
+# Each round3_step() takes about 4.2 clocks (8 instructions, 1.9 IPC)
+{ my $round3_alter=0;
+sub round3_step
+{
+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+    $code .= " mov	%ecx,		%r11d		/* (NEXT STEP) y' = %ecx */\n" if ($pos == -1);
+    $code .= <<EOF;
+	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
+	xor	$z,		%r11d		/* z ^ ... */
+	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
+	xor	$x,		%r11d		/* x ^ ... */
+	add	%r11d,		$dst		/* dst += ... */
+EOF
+    $code .= <<EOF if ($round3_alter);
+	rol	\$$s,		$dst		/* dst <<< s */
+	mov	$x,		%r11d		/* (NEXT STEP) y' = $x */
+EOF
+    $code .= <<EOF if (!$round3_alter);
+	mov	$x,		%r11d		/* (NEXT STEP) y' = $x */
+	rol	\$$s,		$dst		/* dst <<< s */
+EOF
+    $code .= <<EOF;
+	add	$x,		$dst		/* dst += x */
+EOF
+    $round3_alter^=1;
+}
+}
+
+# round4_step() does:
+#   dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s)
+#   %r10d = X[k_next]
+#   %r11d = not z' (copy of not z for the next step)
+# Each round4_step() takes about 5.2 clocks (9 instructions, 1.7 IPC)
+sub round4_step
+{
+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
+    $code .= " mov	\$0xffffffff,	%r11d\n" if ($pos == -1);
+    $code .= " xor	%edx,		%r11d		/* (NEXT STEP) not z' = not %edx*/\n"
+    if ($pos == -1);
+    $code .= <<EOF;
+	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
+	or	$x,		%r11d		/* x | ... */
+	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
+	xor	$y,		%r11d		/* y ^ ... */
+	add	%r11d,		$dst		/* dst += ... */
+	mov	\$0xffffffff,	%r11d
+	rol	\$$s,		$dst		/* dst <<< s */
+	xor	$y,		%r11d		/* (NEXT STEP) not z' = not $y */
+	add	$x,		$dst		/* dst += x */
+EOF
+}
+
+no warnings qw(uninitialized);
+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;
+
+$code .= <<EOF;
+.text
+.align 16
+
+.globl md5_block_asm_data_order
+.type md5_block_asm_data_order,\@function,3
+md5_block_asm_data_order:
+.cfi_startproc
+	push	%rbp
+.cfi_push	%rbp
+	push	%rbx
+.cfi_push	%rbx
+	push	%r12
+.cfi_push	%r12
+	push	%r14
+.cfi_push	%r14
+	push	%r15
+.cfi_push	%r15
+.Lprologue:
+
+	# rdi = arg #1 (ctx, MD5_CTX pointer)
+	# rsi = arg #2 (ptr, data pointer)
+	# rdx = arg #3 (nbr, number of 16-word blocks to process)
+	mov	%rdi,		%rbp	# rbp = ctx
+	shl	\$6,		%rdx	# rdx = nbr in bytes
+	lea	(%rsi,%rdx),	%rdi	# rdi = end
+	mov	0*4(%rbp),	%eax	# eax = ctx->A
+	mov	1*4(%rbp),	%ebx	# ebx = ctx->B
+	mov	2*4(%rbp),	%ecx	# ecx = ctx->C
+	mov	3*4(%rbp),	%edx	# edx = ctx->D
+	# end is 'rdi'
+	# ptr is 'rsi'
+	# A is 'eax'
+	# B is 'ebx'
+	# C is 'ecx'
+	# D is 'edx'
+
+	cmp	%rdi,		%rsi		# cmp end with ptr
+	je	.Lend				# jmp if ptr == end
+
+	# BEGIN of loop over 16-word blocks
+.Lloop:	# save old values of A, B, C, D
+	mov	%eax,		%r8d
+	mov	%ebx,		%r9d
+	mov	%ecx,		%r14d
+	mov	%edx,		%r15d
+EOF
+round1_step(-1,'%eax','%ebx','%ecx','%edx', '1','0xd76aa478', '7');
+round1_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xe8c7b756','12');
+round1_step( 0,'%ecx','%edx','%eax','%ebx', '3','0x242070db','17');
+round1_step( 0,'%ebx','%ecx','%edx','%eax', '4','0xc1bdceee','22');
+round1_step( 0,'%eax','%ebx','%ecx','%edx', '5','0xf57c0faf', '7');
+round1_step( 0,'%edx','%eax','%ebx','%ecx', '6','0x4787c62a','12');
+round1_step( 0,'%ecx','%edx','%eax','%ebx', '7','0xa8304613','17');
+round1_step( 0,'%ebx','%ecx','%edx','%eax', '8','0xfd469501','22');
+round1_step( 0,'%eax','%ebx','%ecx','%edx', '9','0x698098d8', '7');
+round1_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8b44f7af','12');
+round1_step( 0,'%ecx','%edx','%eax','%ebx','11','0xffff5bb1','17');
+round1_step( 0,'%ebx','%ecx','%edx','%eax','12','0x895cd7be','22');
+round1_step( 0,'%eax','%ebx','%ecx','%edx','13','0x6b901122', '7');
+round1_step( 0,'%edx','%eax','%ebx','%ecx','14','0xfd987193','12');
+round1_step( 0,'%ecx','%edx','%eax','%ebx','15','0xa679438e','17');
+round1_step( 1,'%ebx','%ecx','%edx','%eax', '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 .= <<EOF;
+	# add old values of A, B, C, D
+	add	%r8d,	%eax
+	add	%r9d,	%ebx
+	add	%r14d,	%ecx
+	add	%r15d,	%edx
+
+	# loop control
+	add	\$64,		%rsi		# ptr += 64
+	cmp	%rdi,		%rsi		# cmp end with ptr
+	jb	.Lloop				# jmp if ptr < end
+	# END of loop over 16-word blocks
+
+.Lend:
+	mov	%eax,		0*4(%rbp)	# ctx->A = A
+	mov	%ebx,		1*4(%rbp)	# ctx->B = B
+	mov	%ecx,		2*4(%rbp)	# ctx->C = C
+	mov	%edx,		3*4(%rbp)	# ctx->D = D
+
+	mov	(%rsp),%r15
+.cfi_restore	%r15
+	mov	8(%rsp),%r14
+.cfi_restore	%r14
+	mov	16(%rsp),%r12
+.cfi_restore	%r12
+	mov	24(%rsp),%rbx
+.cfi_restore	%rbx
+	mov	32(%rsp),%rbp
+.cfi_restore	%rbp
+	add	\$40,%rsp
+.cfi_adjust_cfa_offset	-40
+.Lepilogue:
+	ret
+.cfi_endproc
+.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 or die "error closing STDOUT: $!";
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/md5/build.info b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/build.info
new file mode 100644
index 0000000..e641fec
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/build.info
@@ -0,0 +1,11 @@
+LIBS=../../libcrypto
+SOURCE[../../libcrypto]=\
+        md5_dgst.c md5_one.c {- $target{md5_asm_src} -}
+
+GENERATE[md5-586.s]=asm/md5-586.pl \
+        $(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS)
+
+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]=..
diff --git a/ap/lib/libssl/openssl-1.1.1o/crypto/md5/md5_dgst.c b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/md5_dgst.c
new file mode 100644
index 0000000..d84cba3
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/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 <stdio.h>
+#include "md5_local.h"
+#include <openssl/opensslv.h>
+
+/*
+ * 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_local.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/ap/lib/libssl/openssl-1.1.1o/crypto/md5/md5_local.h b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/md5_local.h
new file mode 100644
index 0000000..b0087be
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/md5_local.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 <stdlib.h>
+#include <string.h>
+#include <openssl/e_os2.h>
+#include <openssl/md5.h>
+
+#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 "crypto/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/ap/lib/libssl/openssl-1.1.1o/crypto/md5/md5_one.c b/ap/lib/libssl/openssl-1.1.1o/crypto/md5/md5_one.c
new file mode 100644
index 0000000..c3bf2f8
--- /dev/null
+++ b/ap/lib/libssl/openssl-1.1.1o/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 <stdio.h>
+#include <string.h>
+#include <openssl/md5.h>
+#include <openssl/crypto.h>
+
+#ifdef CHARSET_EBCDIC
+# include <openssl/ebcdic.h>
+#endif
+
+unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)
+{
+    MD5_CTX c;
+    static unsigned char m[MD5_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    if (!MD5_Init(&c))
+        return NULL;
+#ifndef CHARSET_EBCDIC
+    MD5_Update(&c, d, n);
+#else
+    {
+        char temp[1024];
+        unsigned long chunk;
+
+        while (n > 0) {
+            chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
+            ebcdic2ascii(temp, d, chunk);
+            MD5_Update(&c, temp, chunk);
+            n -= chunk;
+            d += chunk;
+        }
+    }
+#endif
+    MD5_Final(md, &c);
+    OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
+    return md;
+}