2 # Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
4 # Licensed under the Apache License 2.0 (the "License"). You may not use
5 # this file except in compliance with the License. You can obtain a copy
6 # in the file LICENSE in the source distribution or at
7 # https://www.openssl.org/source/license.html
9 # This module implements support for Armv8 SM3 instructions
11 # $output is the last argument if it looks like a file (it has an extension)
12 # $flavour is the first argument if it doesn't look like a file
13 $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
14 $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
16 $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
17 ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
18 ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
19 die "can't locate arm-xlate.pl";
21 open OUT,"| \"$^X\" $xlate $flavour \"$output\""
22 or die "can't call $xlate: $!";
26 # Wj <- P1(W[j-16]^W[j-9]^(W[j-3]<<<15))^(W[j-13]<<<7)^W[j-6]
27 # Input: s0, s1, s2, s3
28 # s0 = w0 | w1 | w2 | w3
29 # s1 = w4 | w5 | w6 | w7
30 # s2 = w8 | w9 | w10 | w11
31 # s3 = w12 | w13 | w14 | w15
42 // s4 = w7 | w8 | w9 | w10
43 ext $s4.16b, $s1.16b, $s2.16b, #12
44 // vtmp1 = w3 | w4 | w5 | w6
45 ext $vtmp1.16b, $s0.16b, $s1.16b, #12
46 // vtmp2 = w10 | w11 | w12 | w13
47 ext $vtmp2.16b, $s2.16b, $s3.16b, #8
48 sm3partw1 $s4.4s, $s0.4s, $s3.4s
49 sm3partw2 $s4.4s, $vtmp2.4s, $vtmp1.4s
53 # A round of compresson function
55 # ab - choose instruction among sm3tt1a, sm3tt1b, sm3tt2a, sm3tt2b
56 # vstate0 - vstate1, store digest status(A - H)
57 # vconst0 - vconst1, interleaved used to store Tj <<< j
58 # vtmp - temporary register
59 # vw - for sm3tt1ab, vw = s0 eor s1
60 # s0 - for sm3tt2ab, just be s0
61 # i, choose wj' or wj from vw
73 sm3ss1 $vtmp.4s, $vstate0.4s, $vconst0.4s, $vstate1.4s
74 shl $vconst1.4s, $vconst0.4s, #1
75 sri $vconst1.4s, $vconst0.4s, #31
76 sm3tt1$ab $vstate0.4s, $vtmp.4s, $vw.4s[$i]
77 sm3tt2$ab $vstate1.4s, $vtmp.4s, $s0.4s[$i]
95 &msg_exp($s0, $s1, $s2, $s3, $s4, $vtmp1, $vtmp2);
98 eor $vtmp1.16b, $s0.16b, $s1.16b
100 &round($ab, $vstate0, $vstate1, $vconst0, $vconst1, $vtmp2,
102 &round($ab, $vstate0, $vstate1, $vconst1, $vconst0, $vtmp2,
104 &round($ab, $vstate0, $vstate1, $vconst0, $vconst1, $vtmp2,
106 &round($ab, $vstate0, $vstate1, $vconst1, $vconst0, $vtmp2,
111 #include "arm_arch.h"
117 my ($pstate,$pdata,$num)=("x0","x1","w2");
118 my ($state1,$state2)=("v5","v6");
119 my ($sconst1, $sconst2)=("s16","s17");
120 my ($vconst1, $vconst2)=("v16","v17");
121 my ($s0,$s1,$s2,$s3,$s4)=map("v$_",(0..4));
122 my ($bkstate1,$bkstate2)=("v18","v19");
123 my ($vconst_tmp1,$vconst_tmp2)=("v20","v21");
124 my ($vtmp1,$vtmp2)=("v22","v23");
126 # void ossl_hwsm3_block_data_order(SM3_CTX *c, const void *p, size_t num)
128 .globl ossl_hwsm3_block_data_order
129 .type ossl_hwsm3_block_data_order,%function
131 ossl_hwsm3_block_data_order:
132 AARCH64_VALID_CALL_TARGET
134 ld1 {$state1.4s-$state2.4s}, [$pstate]
135 rev64 $state1.4s, $state1.4s
136 rev64 $state2.4s, $state2.4s
137 ext $state1.16b, $state1.16b, $state1.16b, #8
138 ext $state2.16b, $state2.16b, $state2.16b, #8
141 ldp $sconst1, $sconst2, [$constaddr]
145 ld1 {$s0.16b-$s3.16b}, [$pdata], #64
148 mov $bkstate1.16b, $state1.16b
149 mov $bkstate2.16b, $state2.16b
152 rev32 $s0.16b, $s0.16b
153 rev32 $s1.16b, $s1.16b
154 rev32 $s2.16b, $s2.16b
155 rev32 $s3.16b, $s3.16b
158 ext $vconst_tmp1.16b, $vconst1.16b, $vconst1.16b, #4
160 &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
161 $s0,$s1,$s2,$s3,$s4);
162 &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
163 $s1,$s2,$s3,$s4,$s0);
164 &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
165 $s2,$s3,$s4,$s0,$s1);
166 &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
167 $s3,$s4,$s0,$s1,$s2);
170 ext $vconst_tmp1.16b, $vconst2.16b, $vconst2.16b, #4
173 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
174 $s4,$s0,$s1,$s2,$s3);
175 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
176 $s0,$s1,$s2,$s3,$s4);
177 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
178 $s1,$s2,$s3,$s4,$s0);
179 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
180 $s2,$s3,$s4,$s0,$s1);
181 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
182 $s3,$s4,$s0,$s1,$s2);
183 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
184 $s4,$s0,$s1,$s2,$s3);
185 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
186 $s0,$s1,$s2,$s3,$s4);
187 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
188 $s1,$s2,$s3,$s4,$s0);
189 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
190 $s2,$s3,$s4,$s0,$s1);
191 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
193 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
195 &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
199 eor $state1.16b, $state1.16b, $bkstate1.16b
200 eor $state2.16b, $state2.16b, $bkstate2.16b
202 // any remained blocks?
206 rev64 $state1.4s, $state1.4s
207 rev64 $state2.4s, $state2.4s
208 ext $state1.16b, $state1.16b, $state1.16b, #8
209 ext $state2.16b, $state2.16b, $state2.16b, #8
210 st1 {$state1.4s-$state2.4s}, [$pstate]
212 .size ossl_hwsm3_block_data_order,.-ossl_hwsm3_block_data_order
216 .word 0x79cc4519, 0x9d8a7a87
220 #########################################
221 my %sm3partopcode = (
222 "sm3partw1" => 0xce60C000,
223 "sm3partw2" => 0xce60C400);
226 "sm3ssl" => 0xce400000);
229 "sm3tt1a" => 0xce408000,
230 "sm3tt1b" => 0xce408400,
231 "sm3tt2a" => 0xce408800,
232 "sm3tt2b" => 0xce408C00);
235 my ($mnemonic,$arg)=@_;
237 $arg=~ m/[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,\s*[qv](\d+)/o
239 sprintf ".inst\t0x%08x\t//%s %s",
240 $sm3partopcode{$mnemonic}|$1|($2<<5)|($3<<16),
245 my ($mnemonic,$arg)=@_;
247 $arg=~ m/[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,
250 sprintf ".inst\t0x%08x\t//%s %s",
251 $sm3sslopcode{$mnemonic}|$1|($2<<5)|($3<<16)|($4<<10),
256 my ($mnemonic,$arg)=@_;
258 $arg=~ m/[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*\[([0-3])\]/o
260 sprintf ".inst\t0x%08x\t//%s %s",
261 $sm3ttopcode{$mnemonic}|$1|($2<<5)|($3<<16)|($4<<12),
268 last if (!s/^#/\/\// and !/^$/);
273 foreach(split("\n",$code)) {
274 s/\`([^\`]*)\`/eval($1)/ge;
276 s/\b(sm3partw[1-2])\s+([qv].*)/unsm3part($1,$2)/ge;
277 s/\b(sm3ssl)\s+([qv].*)/unsm3ssl($1,$2)/ge;
278 s/\b(sm3tt[1-2][a-b])\s+([qv].*)/unsm3tt($1,$2)/ge;
282 close STDOUT or die "error closing STDOUT: $!";