1#! /usr/bin/env perl
2# This file is dual-licensed, meaning that you can use it under your
3# choice of either of the following two licenses:
4#
5# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
6#
7# Licensed under the Apache License 2.0 (the "License"). You can obtain
8# a copy in the file LICENSE in the source distribution or at
9# https://www.openssl.org/source/license.html
10#
11# or
12#
13# Copyright (c) 2023, Christoph Müllner <christoph.muellner@vrull.eu>
14# Copyright (c) 2023, Phoebe Chen <phoebe.chen@sifive.com>
15# All rights reserved.
16#
17# Redistribution and use in source and binary forms, with or without
18# modification, are permitted provided that the following conditions
19# are met:
20# 1. Redistributions of source code must retain the above copyright
21#    notice, this list of conditions and the following disclaimer.
22# 2. Redistributions in binary form must reproduce the above copyright
23#    notice, this list of conditions and the following disclaimer in the
24#    documentation and/or other materials provided with the distribution.
25#
26# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
38# - RV64I
39# - RISC-V Vector ('V') with VLEN >= 128
40# - RISC-V Vector AES block cipher extension ('Zvkned')
41
42use strict;
43use warnings;
44
45use FindBin qw($Bin);
46use lib "$Bin";
47use lib "$Bin/../../perlasm";
48use riscv;
49
50# $output is the last argument if it looks like a file (it has an extension)
51# $flavour is the first argument if it doesn't look like a file
52my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
53my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
54
55$output and open STDOUT,">$output";
56
57my $code=<<___;
58.text
59___
60
61my ($V0, $V1, $V2, $V3, $V4, $V5, $V6, $V7,
62    $V8, $V9, $V10, $V11, $V12, $V13, $V14, $V15,
63    $V16, $V17, $V18, $V19, $V20, $V21, $V22, $V23,
64    $V24, $V25, $V26, $V27, $V28, $V29, $V30, $V31,
65) = map("v$_",(0..31));
66
67# Load all 11 round keys to v1-v11 registers.
68sub aes_128_load_key {
69    my $KEYP = shift;
70
71    my $code=<<___;
72    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
73    @{[vle32_v $V1, $KEYP]}
74    addi $KEYP, $KEYP, 16
75    @{[vle32_v $V2, $KEYP]}
76    addi $KEYP, $KEYP, 16
77    @{[vle32_v $V3, $KEYP]}
78    addi $KEYP, $KEYP, 16
79    @{[vle32_v $V4, $KEYP]}
80    addi $KEYP, $KEYP, 16
81    @{[vle32_v $V5, $KEYP]}
82    addi $KEYP, $KEYP, 16
83    @{[vle32_v $V6, $KEYP]}
84    addi $KEYP, $KEYP, 16
85    @{[vle32_v $V7, $KEYP]}
86    addi $KEYP, $KEYP, 16
87    @{[vle32_v $V8, $KEYP]}
88    addi $KEYP, $KEYP, 16
89    @{[vle32_v $V9, $KEYP]}
90    addi $KEYP, $KEYP, 16
91    @{[vle32_v $V10, $KEYP]}
92    addi $KEYP, $KEYP, 16
93    @{[vle32_v $V11, $KEYP]}
94___
95
96    return $code;
97}
98
99# Load all 13 round keys to v1-v13 registers.
100sub aes_192_load_key {
101    my $KEYP = shift;
102
103    my $code=<<___;
104    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
105    @{[vle32_v $V1, $KEYP]}
106    addi $KEYP, $KEYP, 16
107    @{[vle32_v $V2, $KEYP]}
108    addi $KEYP, $KEYP, 16
109    @{[vle32_v $V3, $KEYP]}
110    addi $KEYP, $KEYP, 16
111    @{[vle32_v $V4, $KEYP]}
112    addi $KEYP, $KEYP, 16
113    @{[vle32_v $V5, $KEYP]}
114    addi $KEYP, $KEYP, 16
115    @{[vle32_v $V6, $KEYP]}
116    addi $KEYP, $KEYP, 16
117    @{[vle32_v $V7, $KEYP]}
118    addi $KEYP, $KEYP, 16
119    @{[vle32_v $V8, $KEYP]}
120    addi $KEYP, $KEYP, 16
121    @{[vle32_v $V9, $KEYP]}
122    addi $KEYP, $KEYP, 16
123    @{[vle32_v $V10, $KEYP]}
124    addi $KEYP, $KEYP, 16
125    @{[vle32_v $V11, $KEYP]}
126    addi $KEYP, $KEYP, 16
127    @{[vle32_v $V12, $KEYP]}
128    addi $KEYP, $KEYP, 16
129    @{[vle32_v $V13, $KEYP]}
130___
131
132    return $code;
133}
134
135# Load all 15 round keys to v1-v15 registers.
136sub aes_256_load_key {
137    my $KEYP = shift;
138
139    my $code=<<___;
140    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
141    @{[vle32_v $V1, $KEYP]}
142    addi $KEYP, $KEYP, 16
143    @{[vle32_v $V2, $KEYP]}
144    addi $KEYP, $KEYP, 16
145    @{[vle32_v $V3, $KEYP]}
146    addi $KEYP, $KEYP, 16
147    @{[vle32_v $V4, $KEYP]}
148    addi $KEYP, $KEYP, 16
149    @{[vle32_v $V5, $KEYP]}
150    addi $KEYP, $KEYP, 16
151    @{[vle32_v $V6, $KEYP]}
152    addi $KEYP, $KEYP, 16
153    @{[vle32_v $V7, $KEYP]}
154    addi $KEYP, $KEYP, 16
155    @{[vle32_v $V8, $KEYP]}
156    addi $KEYP, $KEYP, 16
157    @{[vle32_v $V9, $KEYP]}
158    addi $KEYP, $KEYP, 16
159    @{[vle32_v $V10, $KEYP]}
160    addi $KEYP, $KEYP, 16
161    @{[vle32_v $V11, $KEYP]}
162    addi $KEYP, $KEYP, 16
163    @{[vle32_v $V12, $KEYP]}
164    addi $KEYP, $KEYP, 16
165    @{[vle32_v $V13, $KEYP]}
166    addi $KEYP, $KEYP, 16
167    @{[vle32_v $V14, $KEYP]}
168    addi $KEYP, $KEYP, 16
169    @{[vle32_v $V15, $KEYP]}
170___
171
172    return $code;
173}
174
175# aes-128 encryption with round keys v1-v11
176sub aes_128_encrypt {
177    my $code=<<___;
178    @{[vaesz_vs $V24, $V1]}     # with round key w[ 0, 3]
179    @{[vaesem_vs $V24, $V2]}    # with round key w[ 4, 7]
180    @{[vaesem_vs $V24, $V3]}    # with round key w[ 8,11]
181    @{[vaesem_vs $V24, $V4]}    # with round key w[12,15]
182    @{[vaesem_vs $V24, $V5]}    # with round key w[16,19]
183    @{[vaesem_vs $V24, $V6]}    # with round key w[20,23]
184    @{[vaesem_vs $V24, $V7]}    # with round key w[24,27]
185    @{[vaesem_vs $V24, $V8]}    # with round key w[28,31]
186    @{[vaesem_vs $V24, $V9]}    # with round key w[32,35]
187    @{[vaesem_vs $V24, $V10]}   # with round key w[36,39]
188    @{[vaesef_vs $V24, $V11]}   # with round key w[40,43]
189___
190
191    return $code;
192}
193
194# aes-128 decryption with round keys v1-v11
195sub aes_128_decrypt {
196    my $code=<<___;
197    @{[vaesz_vs $V24, $V11]}   # with round key w[40,43]
198    @{[vaesdm_vs $V24, $V10]}  # with round key w[36,39]
199    @{[vaesdm_vs $V24, $V9]}   # with round key w[32,35]
200    @{[vaesdm_vs $V24, $V8]}   # with round key w[28,31]
201    @{[vaesdm_vs $V24, $V7]}   # with round key w[24,27]
202    @{[vaesdm_vs $V24, $V6]}   # with round key w[20,23]
203    @{[vaesdm_vs $V24, $V5]}   # with round key w[16,19]
204    @{[vaesdm_vs $V24, $V4]}   # with round key w[12,15]
205    @{[vaesdm_vs $V24, $V3]}   # with round key w[ 8,11]
206    @{[vaesdm_vs $V24, $V2]}   # with round key w[ 4, 7]
207    @{[vaesdf_vs $V24, $V1]}   # with round key w[ 0, 3]
208___
209
210    return $code;
211}
212
213# aes-192 encryption with round keys v1-v13
214sub aes_192_encrypt {
215    my $code=<<___;
216    @{[vaesz_vs $V24, $V1]}     # with round key w[ 0, 3]
217    @{[vaesem_vs $V24, $V2]}    # with round key w[ 4, 7]
218    @{[vaesem_vs $V24, $V3]}    # with round key w[ 8,11]
219    @{[vaesem_vs $V24, $V4]}    # with round key w[12,15]
220    @{[vaesem_vs $V24, $V5]}    # with round key w[16,19]
221    @{[vaesem_vs $V24, $V6]}    # with round key w[20,23]
222    @{[vaesem_vs $V24, $V7]}    # with round key w[24,27]
223    @{[vaesem_vs $V24, $V8]}    # with round key w[28,31]
224    @{[vaesem_vs $V24, $V9]}    # with round key w[32,35]
225    @{[vaesem_vs $V24, $V10]}   # with round key w[36,39]
226    @{[vaesem_vs $V24, $V11]}   # with round key w[40,43]
227    @{[vaesem_vs $V24, $V12]}   # with round key w[44,47]
228    @{[vaesef_vs $V24, $V13]}   # with round key w[48,51]
229___
230
231    return $code;
232}
233
234# aes-192 decryption with round keys v1-v13
235sub aes_192_decrypt {
236    my $code=<<___;
237    @{[vaesz_vs $V24, $V13]}    # with round key w[48,51]
238    @{[vaesdm_vs $V24, $V12]}   # with round key w[44,47]
239    @{[vaesdm_vs $V24, $V11]}   # with round key w[40,43]
240    @{[vaesdm_vs $V24, $V10]}   # with round key w[36,39]
241    @{[vaesdm_vs $V24, $V9]}    # with round key w[32,35]
242    @{[vaesdm_vs $V24, $V8]}    # with round key w[28,31]
243    @{[vaesdm_vs $V24, $V7]}    # with round key w[24,27]
244    @{[vaesdm_vs $V24, $V6]}    # with round key w[20,23]
245    @{[vaesdm_vs $V24, $V5]}    # with round key w[16,19]
246    @{[vaesdm_vs $V24, $V4]}    # with round key w[12,15]
247    @{[vaesdm_vs $V24, $V3]}    # with round key w[ 8,11]
248    @{[vaesdm_vs $V24, $V2]}    # with round key w[ 4, 7]
249    @{[vaesdf_vs $V24, $V1]}    # with round key w[ 0, 3]
250___
251
252    return $code;
253}
254
255# aes-256 encryption with round keys v1-v15
256sub aes_256_encrypt {
257    my $code=<<___;
258    @{[vaesz_vs $V24, $V1]}     # with round key w[ 0, 3]
259    @{[vaesem_vs $V24, $V2]}    # with round key w[ 4, 7]
260    @{[vaesem_vs $V24, $V3]}    # with round key w[ 8,11]
261    @{[vaesem_vs $V24, $V4]}    # with round key w[12,15]
262    @{[vaesem_vs $V24, $V5]}    # with round key w[16,19]
263    @{[vaesem_vs $V24, $V6]}    # with round key w[20,23]
264    @{[vaesem_vs $V24, $V7]}    # with round key w[24,27]
265    @{[vaesem_vs $V24, $V8]}    # with round key w[28,31]
266    @{[vaesem_vs $V24, $V9]}    # with round key w[32,35]
267    @{[vaesem_vs $V24, $V10]}   # with round key w[36,39]
268    @{[vaesem_vs $V24, $V11]}   # with round key w[40,43]
269    @{[vaesem_vs $V24, $V12]}   # with round key w[44,47]
270    @{[vaesem_vs $V24, $V13]}   # with round key w[48,51]
271    @{[vaesem_vs $V24, $V14]}   # with round key w[52,55]
272    @{[vaesef_vs $V24, $V15]}   # with round key w[56,59]
273___
274
275    return $code;
276}
277
278# aes-256 decryption with round keys v1-v15
279sub aes_256_decrypt {
280    my $code=<<___;
281    @{[vaesz_vs $V24, $V15]}    # with round key w[56,59]
282    @{[vaesdm_vs $V24, $V14]}   # with round key w[52,55]
283    @{[vaesdm_vs $V24, $V13]}   # with round key w[48,51]
284    @{[vaesdm_vs $V24, $V12]}   # with round key w[44,47]
285    @{[vaesdm_vs $V24, $V11]}   # with round key w[40,43]
286    @{[vaesdm_vs $V24, $V10]}   # with round key w[36,39]
287    @{[vaesdm_vs $V24, $V9]}    # with round key w[32,35]
288    @{[vaesdm_vs $V24, $V8]}    # with round key w[28,31]
289    @{[vaesdm_vs $V24, $V7]}    # with round key w[24,27]
290    @{[vaesdm_vs $V24, $V6]}    # with round key w[20,23]
291    @{[vaesdm_vs $V24, $V5]}    # with round key w[16,19]
292    @{[vaesdm_vs $V24, $V4]}    # with round key w[12,15]
293    @{[vaesdm_vs $V24, $V3]}    # with round key w[ 8,11]
294    @{[vaesdm_vs $V24, $V2]}    # with round key w[ 4, 7]
295    @{[vaesdf_vs $V24, $V1]}    # with round key w[ 0, 3]
296___
297
298    return $code;
299}
300
301{
302###############################################################################
303# void rv64i_zvkned_cbc_encrypt(const unsigned char *in, unsigned char *out,
304#                               size_t length, const AES_KEY *key,
305#                               unsigned char *ivec, const int enc);
306my ($INP, $OUTP, $LEN, $KEYP, $IVP, $ENC) = ("a0", "a1", "a2", "a3", "a4", "a5");
307my ($T0, $T1, $ROUNDS) = ("t0", "t1", "t2");
308
309$code .= <<___;
310.p2align 3
311.globl rv64i_zvkned_cbc_encrypt
312.type rv64i_zvkned_cbc_encrypt,\@function
313rv64i_zvkned_cbc_encrypt:
314    # check whether the length is a multiple of 16 and >= 16
315    li $T1, 16
316    blt $LEN, $T1, L_end
317    andi $T1, $LEN, 15
318    bnez $T1, L_end
319
320    # Load number of rounds
321    lwu $ROUNDS, 240($KEYP)
322
323    # Get proper routine for key size
324    li $T0, 10
325    beq $ROUNDS, $T0, L_cbc_enc_128
326
327    li $T0, 12
328    beq $ROUNDS, $T0, L_cbc_enc_192
329
330    li $T0, 14
331    beq $ROUNDS, $T0, L_cbc_enc_256
332
333    ret
334.size rv64i_zvkned_cbc_encrypt,.-rv64i_zvkned_cbc_encrypt
335___
336
337$code .= <<___;
338.p2align 3
339L_cbc_enc_128:
340    # Load all 11 round keys to v1-v11 registers.
341    @{[aes_128_load_key $KEYP]}
342
343    # Load IV.
344    @{[vle32_v $V16, $IVP]}
345
346    @{[vle32_v $V24, $INP]}
347    @{[vxor_vv $V24, $V24, $V16]}
348    j 2f
349
3501:
351    @{[vle32_v $V17, $INP]}
352    @{[vxor_vv $V24, $V24, $V17]}
353
3542:
355    # AES body
356    @{[aes_128_encrypt]}
357
358    @{[vse32_v $V24, $OUTP]}
359
360    addi $INP, $INP, 16
361    addi $OUTP, $OUTP, 16
362    addi $LEN, $LEN, -16
363
364    bnez $LEN, 1b
365
366    @{[vse32_v $V24, $IVP]}
367
368    ret
369.size L_cbc_enc_128,.-L_cbc_enc_128
370___
371
372$code .= <<___;
373.p2align 3
374L_cbc_enc_192:
375    # Load all 13 round keys to v1-v13 registers.
376    @{[aes_192_load_key $KEYP]}
377
378    # Load IV.
379    @{[vle32_v $V16, $IVP]}
380
381    @{[vle32_v $V24, $INP]}
382    @{[vxor_vv $V24, $V24, $V16]}
383    j 2f
384
3851:
386    @{[vle32_v $V17, $INP]}
387    @{[vxor_vv $V24, $V24, $V17]}
388
3892:
390    # AES body
391    @{[aes_192_encrypt]}
392
393    @{[vse32_v $V24, $OUTP]}
394
395    addi $INP, $INP, 16
396    addi $OUTP, $OUTP, 16
397    addi $LEN, $LEN, -16
398
399    bnez $LEN, 1b
400
401    @{[vse32_v $V24, $IVP]}
402
403    ret
404.size L_cbc_enc_192,.-L_cbc_enc_192
405___
406
407$code .= <<___;
408.p2align 3
409L_cbc_enc_256:
410    # Load all 15 round keys to v1-v15 registers.
411    @{[aes_256_load_key $KEYP]}
412
413    # Load IV.
414    @{[vle32_v $V16, $IVP]}
415
416    @{[vle32_v $V24, $INP]}
417    @{[vxor_vv $V24, $V24, $V16]}
418    j 2f
419
4201:
421    @{[vle32_v $V17, $INP]}
422    @{[vxor_vv $V24, $V24, $V17]}
423
4242:
425    # AES body
426    @{[aes_256_encrypt]}
427
428    @{[vse32_v $V24, $OUTP]}
429
430    addi $INP, $INP, 16
431    addi $OUTP, $OUTP, 16
432    addi $LEN, $LEN, -16
433
434    bnez $LEN, 1b
435
436    @{[vse32_v $V24, $IVP]}
437
438    ret
439.size L_cbc_enc_256,.-L_cbc_enc_256
440___
441
442###############################################################################
443# void rv64i_zvkned_cbc_decrypt(const unsigned char *in, unsigned char *out,
444#                               size_t length, const AES_KEY *key,
445#                               unsigned char *ivec, const int enc);
446
447$code .= <<___;
448.p2align 3
449.globl rv64i_zvkned_cbc_decrypt
450.type rv64i_zvkned_cbc_decrypt,\@function
451rv64i_zvkned_cbc_decrypt:
452    # check whether the length is a multiple of 16 and >= 16
453    li $T1, 16
454    blt $LEN, $T1, L_end
455    andi $T1, $LEN, 15
456    bnez $T1, L_end
457
458    # Load number of rounds
459    lwu $ROUNDS, 240($KEYP)
460
461    # Get proper routine for key size
462    li $T0, 10
463    beq $ROUNDS, $T0, L_cbc_dec_128
464
465    li $T0, 12
466    beq $ROUNDS, $T0, L_cbc_dec_192
467
468    li $T0, 14
469    beq $ROUNDS, $T0, L_cbc_dec_256
470
471    ret
472.size rv64i_zvkned_cbc_decrypt,.-rv64i_zvkned_cbc_decrypt
473___
474
475$code .= <<___;
476.p2align 3
477L_cbc_dec_128:
478    # Load all 11 round keys to v1-v11 registers.
479    @{[aes_128_load_key $KEYP]}
480
481    # Load IV.
482    @{[vle32_v $V16, $IVP]}
483
484    @{[vle32_v $V24, $INP]}
485    @{[vmv_v_v $V17, $V24]}
486    j 2f
487
4881:
489    @{[vle32_v $V24, $INP]}
490    @{[vmv_v_v $V17, $V24]}
491    addi $OUTP, $OUTP, 16
492
4932:
494    # AES body
495    @{[aes_128_decrypt]}
496
497    @{[vxor_vv $V24, $V24, $V16]}
498    @{[vse32_v $V24, $OUTP]}
499    @{[vmv_v_v $V16, $V17]}
500
501    addi $LEN, $LEN, -16
502    addi $INP, $INP, 16
503
504    bnez $LEN, 1b
505
506    @{[vse32_v $V16, $IVP]}
507
508    ret
509.size L_cbc_dec_128,.-L_cbc_dec_128
510___
511
512$code .= <<___;
513.p2align 3
514L_cbc_dec_192:
515    # Load all 13 round keys to v1-v13 registers.
516    @{[aes_192_load_key $KEYP]}
517
518    # Load IV.
519    @{[vle32_v $V16, $IVP]}
520
521    @{[vle32_v $V24, $INP]}
522    @{[vmv_v_v $V17, $V24]}
523    j 2f
524
5251:
526    @{[vle32_v $V24, $INP]}
527    @{[vmv_v_v $V17, $V24]}
528    addi $OUTP, $OUTP, 16
529
5302:
531    # AES body
532    @{[aes_192_decrypt]}
533
534    @{[vxor_vv $V24, $V24, $V16]}
535    @{[vse32_v $V24, $OUTP]}
536    @{[vmv_v_v $V16, $V17]}
537
538    addi $LEN, $LEN, -16
539    addi $INP, $INP, 16
540
541    bnez $LEN, 1b
542
543    @{[vse32_v $V16, $IVP]}
544
545    ret
546.size L_cbc_dec_192,.-L_cbc_dec_192
547___
548
549$code .= <<___;
550.p2align 3
551L_cbc_dec_256:
552    # Load all 15 round keys to v1-v15 registers.
553    @{[aes_256_load_key $KEYP]}
554
555    # Load IV.
556    @{[vle32_v $V16, $IVP]}
557
558    @{[vle32_v $V24, $INP]}
559    @{[vmv_v_v $V17, $V24]}
560    j 2f
561
5621:
563    @{[vle32_v $V24, $INP]}
564    @{[vmv_v_v $V17, $V24]}
565    addi $OUTP, $OUTP, 16
566
5672:
568    # AES body
569    @{[aes_256_decrypt]}
570
571    @{[vxor_vv $V24, $V24, $V16]}
572    @{[vse32_v $V24, $OUTP]}
573    @{[vmv_v_v $V16, $V17]}
574
575    addi $LEN, $LEN, -16
576    addi $INP, $INP, 16
577
578    bnez $LEN, 1b
579
580    @{[vse32_v $V16, $IVP]}
581
582    ret
583.size L_cbc_dec_256,.-L_cbc_dec_256
584___
585}
586
587{
588###############################################################################
589# void rv64i_zvkned_ecb_encrypt(const unsigned char *in, unsigned char *out,
590#                               size_t length, const AES_KEY *key,
591#                               const int enc);
592my ($INP, $OUTP, $LEN, $KEYP, $ENC) = ("a0", "a1", "a2", "a3", "a4");
593my ($REMAIN_LEN) = ("a5");
594my ($VL) = ("a6");
595my ($T0, $T1, $ROUNDS) = ("t0", "t1", "t2");
596my ($LEN32) = ("t3");
597
598$code .= <<___;
599.p2align 3
600.globl rv64i_zvkned_ecb_encrypt
601.type rv64i_zvkned_ecb_encrypt,\@function
602rv64i_zvkned_ecb_encrypt:
603    # Make the LEN become e32 length.
604    srli $LEN32, $LEN, 2
605
606    # Load number of rounds
607    lwu $ROUNDS, 240($KEYP)
608
609    # Get proper routine for key size
610    li $T0, 10
611    beq $ROUNDS, $T0, L_ecb_enc_128
612
613    li $T0, 12
614    beq $ROUNDS, $T0, L_ecb_enc_192
615
616    li $T0, 14
617    beq $ROUNDS, $T0, L_ecb_enc_256
618
619    ret
620.size rv64i_zvkned_ecb_encrypt,.-rv64i_zvkned_ecb_encrypt
621___
622
623$code .= <<___;
624.p2align 3
625L_ecb_enc_128:
626    # Load all 11 round keys to v1-v11 registers.
627    @{[aes_128_load_key $KEYP]}
628
6291:
630    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
631    slli $T0, $VL, 2
632    sub $LEN32, $LEN32, $VL
633
634    @{[vle32_v $V24, $INP]}
635
636    # AES body
637    @{[aes_128_encrypt]}
638
639    @{[vse32_v $V24, $OUTP]}
640
641    add $INP, $INP, $T0
642    add $OUTP, $OUTP, $T0
643
644    bnez $LEN32, 1b
645
646    ret
647.size L_ecb_enc_128,.-L_ecb_enc_128
648___
649
650$code .= <<___;
651.p2align 3
652L_ecb_enc_192:
653    # Load all 13 round keys to v1-v13 registers.
654    @{[aes_192_load_key $KEYP]}
655
6561:
657    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
658    slli $T0, $VL, 2
659    sub $LEN32, $LEN32, $VL
660
661    @{[vle32_v $V24, $INP]}
662
663    # AES body
664    @{[aes_192_encrypt]}
665
666    @{[vse32_v $V24, $OUTP]}
667
668    add $INP, $INP, $T0
669    add $OUTP, $OUTP, $T0
670
671    bnez $LEN32, 1b
672
673    ret
674.size L_ecb_enc_192,.-L_ecb_enc_192
675___
676
677$code .= <<___;
678.p2align 3
679L_ecb_enc_256:
680    # Load all 15 round keys to v1-v15 registers.
681    @{[aes_256_load_key $KEYP]}
682
6831:
684    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
685    slli $T0, $VL, 2
686    sub $LEN32, $LEN32, $VL
687
688    @{[vle32_v $V24, $INP]}
689
690    # AES body
691    @{[aes_256_encrypt]}
692
693    @{[vse32_v $V24, $OUTP]}
694
695    add $INP, $INP, $T0
696    add $OUTP, $OUTP, $T0
697
698    bnez $LEN32, 1b
699
700    ret
701.size L_ecb_enc_256,.-L_ecb_enc_256
702___
703
704###############################################################################
705# void rv64i_zvkned_ecb_decrypt(const unsigned char *in, unsigned char *out,
706#                               size_t length, const AES_KEY *key,
707#                               const int enc);
708
709$code .= <<___;
710.p2align 3
711.globl rv64i_zvkned_ecb_decrypt
712.type rv64i_zvkned_ecb_decrypt,\@function
713rv64i_zvkned_ecb_decrypt:
714    # Make the LEN become e32 length.
715    srli $LEN32, $LEN, 2
716
717    # Load number of rounds
718    lwu $ROUNDS, 240($KEYP)
719
720    # Get proper routine for key size
721    li $T0, 10
722    beq $ROUNDS, $T0, L_ecb_dec_128
723
724    li $T0, 12
725    beq $ROUNDS, $T0, L_ecb_dec_192
726
727    li $T0, 14
728    beq $ROUNDS, $T0, L_ecb_dec_256
729
730    ret
731.size rv64i_zvkned_ecb_decrypt,.-rv64i_zvkned_ecb_decrypt
732___
733
734$code .= <<___;
735.p2align 3
736L_ecb_dec_128:
737    # Load all 11 round keys to v1-v11 registers.
738    @{[aes_128_load_key $KEYP]}
739
7401:
741    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
742    slli $T0, $VL, 2
743    sub $LEN32, $LEN32, $VL
744
745    @{[vle32_v $V24, $INP]}
746
747    # AES body
748    @{[aes_128_decrypt]}
749
750    @{[vse32_v $V24, $OUTP]}
751
752    add $INP, $INP, $T0
753    add $OUTP, $OUTP, $T0
754
755    bnez $LEN32, 1b
756
757    ret
758.size L_ecb_dec_128,.-L_ecb_dec_128
759___
760
761$code .= <<___;
762.p2align 3
763L_ecb_dec_192:
764    # Load all 13 round keys to v1-v13 registers.
765    @{[aes_192_load_key $KEYP]}
766
7671:
768    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
769    slli $T0, $VL, 2
770    sub $LEN32, $LEN32, $VL
771
772    @{[vle32_v $V24, $INP]}
773
774    # AES body
775    @{[aes_192_decrypt]}
776
777    @{[vse32_v $V24, $OUTP]}
778
779    add $INP, $INP, $T0
780    add $OUTP, $OUTP, $T0
781
782    bnez $LEN32, 1b
783
784    ret
785.size L_ecb_dec_192,.-L_ecb_dec_192
786___
787
788$code .= <<___;
789.p2align 3
790L_ecb_dec_256:
791    # Load all 15 round keys to v1-v15 registers.
792    @{[aes_256_load_key $KEYP]}
793
7941:
795    @{[vsetvli $VL, $LEN32, "e32", "m4", "ta", "ma"]}
796    slli $T0, $VL, 2
797    sub $LEN32, $LEN32, $VL
798
799    @{[vle32_v $V24, $INP]}
800
801    # AES body
802    @{[aes_256_decrypt]}
803
804    @{[vse32_v $V24, $OUTP]}
805
806    add $INP, $INP, $T0
807    add $OUTP, $OUTP, $T0
808
809    bnez $LEN32, 1b
810
811    ret
812.size L_ecb_dec_256,.-L_ecb_dec_256
813___
814
815}
816
817{
818################################################################################
819# int rv64i_zvkned_set_encrypt_key(const unsigned char *userKey, const int bits,
820#                                  AES_KEY *key)
821# int rv64i_zvkned_set_decrypt_key(const unsigned char *userKey, const int bits,
822#                                  AES_KEY *key)
823my ($UKEY,$BITS,$KEYP) = ("a0", "a1", "a2");
824my ($T0,$T1,$T4) = ("t1", "t2", "t4");
825
826$code .= <<___;
827.p2align 3
828.globl rv64i_zvkned_set_encrypt_key
829.type rv64i_zvkned_set_encrypt_key,\@function
830rv64i_zvkned_set_encrypt_key:
831    beqz $UKEY, L_fail_m1
832    beqz $KEYP, L_fail_m1
833
834    # Get proper routine for key size
835    li $T0, 256
836    beq $BITS, $T0, L_set_key_256
837    li $T0, 128
838    beq $BITS, $T0, L_set_key_128
839
840    j L_fail_m2
841
842.size rv64i_zvkned_set_encrypt_key,.-rv64i_zvkned_set_encrypt_key
843___
844
845$code .= <<___;
846.p2align 3
847.globl rv64i_zvkned_set_decrypt_key
848.type rv64i_zvkned_set_decrypt_key,\@function
849rv64i_zvkned_set_decrypt_key:
850    beqz $UKEY, L_fail_m1
851    beqz $KEYP, L_fail_m1
852
853    # Get proper routine for key size
854    li $T0, 256
855    beq $BITS, $T0, L_set_key_256
856    li $T0, 128
857    beq $BITS, $T0, L_set_key_128
858
859    j L_fail_m2
860
861.size rv64i_zvkned_set_decrypt_key,.-rv64i_zvkned_set_decrypt_key
862___
863
864$code .= <<___;
865.p2align 3
866L_set_key_128:
867    # Store the number of rounds
868    li $T1, 10
869    sw $T1, 240($KEYP)
870
871    @{[vsetivli__x0_4_e32_m1_tu_mu]}
872
873    # Load the key
874    @{[vle32_v $V10, ($UKEY)]}
875
876    # Generate keys for round 2-11 into registers v11-v20.
877    @{[vaeskf1_vi $V11, $V10, 1]}   # v11 <- rk2  (w[ 4, 7])
878    @{[vaeskf1_vi $V12, $V11, 2]}   # v12 <- rk3  (w[ 8,11])
879    @{[vaeskf1_vi $V13, $V12, 3]}   # v13 <- rk4  (w[12,15])
880    @{[vaeskf1_vi $V14, $V13, 4]}   # v14 <- rk5  (w[16,19])
881    @{[vaeskf1_vi $V15, $V14, 5]}   # v15 <- rk6  (w[20,23])
882    @{[vaeskf1_vi $V16, $V15, 6]}   # v16 <- rk7  (w[24,27])
883    @{[vaeskf1_vi $V17, $V16, 7]}   # v17 <- rk8  (w[28,31])
884    @{[vaeskf1_vi $V18, $V17, 8]}   # v18 <- rk9  (w[32,35])
885    @{[vaeskf1_vi $V19, $V18, 9]}   # v19 <- rk10 (w[36,39])
886    @{[vaeskf1_vi $V20, $V19, 10]}  # v20 <- rk11 (w[40,43])
887
888    # Store the round keys
889    @{[vse32_v $V10, $KEYP]}
890    addi $KEYP, $KEYP, 16
891    @{[vse32_v $V11, $KEYP]}
892    addi $KEYP, $KEYP, 16
893    @{[vse32_v $V12, $KEYP]}
894    addi $KEYP, $KEYP, 16
895    @{[vse32_v $V13, $KEYP]}
896    addi $KEYP, $KEYP, 16
897    @{[vse32_v $V14, $KEYP]}
898    addi $KEYP, $KEYP, 16
899    @{[vse32_v $V15, $KEYP]}
900    addi $KEYP, $KEYP, 16
901    @{[vse32_v $V16, $KEYP]}
902    addi $KEYP, $KEYP, 16
903    @{[vse32_v $V17, $KEYP]}
904    addi $KEYP, $KEYP, 16
905    @{[vse32_v $V18, $KEYP]}
906    addi $KEYP, $KEYP, 16
907    @{[vse32_v $V19, $KEYP]}
908    addi $KEYP, $KEYP, 16
909    @{[vse32_v $V20, $KEYP]}
910
911    li a0, 1
912    ret
913.size L_set_key_128,.-L_set_key_128
914___
915
916$code .= <<___;
917.p2align 3
918L_set_key_256:
919    # Store the number of rounds
920    li $T1, 14
921    sw $T1, 240($KEYP)
922
923    @{[vsetivli__x0_4_e32_m1_tu_mu]}
924
925    # Load the key
926    @{[vle32_v $V10, ($UKEY)]}
927    addi $UKEY, $UKEY, 16
928    @{[vle32_v $V11, ($UKEY)]}
929
930    @{[vmv_v_v $V12, $V10]}
931    @{[vaeskf2_vi $V12, $V11, 2]}
932    @{[vmv_v_v $V13, $V11]}
933    @{[vaeskf2_vi $V13, $V12, 3]}
934    @{[vmv_v_v $V14, $V12]}
935    @{[vaeskf2_vi $V14, $V13, 4]}
936    @{[vmv_v_v $V15, $V13]}
937    @{[vaeskf2_vi $V15, $V14, 5]}
938    @{[vmv_v_v $V16, $V14]}
939    @{[vaeskf2_vi $V16, $V15, 6]}
940    @{[vmv_v_v $V17, $V15]}
941    @{[vaeskf2_vi $V17, $V16, 7]}
942    @{[vmv_v_v $V18, $V16]}
943    @{[vaeskf2_vi $V18, $V17, 8]}
944    @{[vmv_v_v $V19, $V17]}
945    @{[vaeskf2_vi $V19, $V18, 9]}
946    @{[vmv_v_v $V20, $V18]}
947    @{[vaeskf2_vi $V20, $V19, 10]}
948    @{[vmv_v_v $V21, $V19]}
949    @{[vaeskf2_vi $V21, $V20, 11]}
950    @{[vmv_v_v $V22, $V20]}
951    @{[vaeskf2_vi $V22, $V21, 12]}
952    @{[vmv_v_v $V23, $V21]}
953    @{[vaeskf2_vi $V23, $V22, 13]}
954    @{[vmv_v_v $V24, $V22]}
955    @{[vaeskf2_vi $V24, $V23, 14]}
956
957    @{[vse32_v $V10, $KEYP]}
958    addi $KEYP, $KEYP, 16
959    @{[vse32_v $V11, $KEYP]}
960    addi $KEYP, $KEYP, 16
961    @{[vse32_v $V12, $KEYP]}
962    addi $KEYP, $KEYP, 16
963    @{[vse32_v $V13, $KEYP]}
964    addi $KEYP, $KEYP, 16
965    @{[vse32_v $V14, $KEYP]}
966    addi $KEYP, $KEYP, 16
967    @{[vse32_v $V15, $KEYP]}
968    addi $KEYP, $KEYP, 16
969    @{[vse32_v $V16, $KEYP]}
970    addi $KEYP, $KEYP, 16
971    @{[vse32_v $V17, $KEYP]}
972    addi $KEYP, $KEYP, 16
973    @{[vse32_v $V18, $KEYP]}
974    addi $KEYP, $KEYP, 16
975    @{[vse32_v $V19, $KEYP]}
976    addi $KEYP, $KEYP, 16
977    @{[vse32_v $V20, $KEYP]}
978    addi $KEYP, $KEYP, 16
979    @{[vse32_v $V21, $KEYP]}
980    addi $KEYP, $KEYP, 16
981    @{[vse32_v $V22, $KEYP]}
982    addi $KEYP, $KEYP, 16
983    @{[vse32_v $V23, $KEYP]}
984    addi $KEYP, $KEYP, 16
985    @{[vse32_v $V24, $KEYP]}
986
987    li a0, 1
988    ret
989.size L_set_key_256,.-L_set_key_256
990___
991}
992
993{
994################################################################################
995# void rv64i_zvkned_encrypt(const unsigned char *in, unsigned char *out,
996#                           const AES_KEY *key);
997my ($INP,$OUTP,$KEYP) = ("a0", "a1", "a2");
998my ($T0,$T1, $ROUNDS, $T6) = ("a3", "a4", "t5", "t6");
999
1000$code .= <<___;
1001.p2align 3
1002.globl rv64i_zvkned_encrypt
1003.type rv64i_zvkned_encrypt,\@function
1004rv64i_zvkned_encrypt:
1005    # Load number of rounds
1006    lwu $ROUNDS, 240($KEYP)
1007
1008    # Get proper routine for key size
1009    li $T6, 14
1010    beq $ROUNDS, $T6, L_enc_256
1011    li $T6, 10
1012    beq $ROUNDS, $T6, L_enc_128
1013    li $T6, 12
1014    beq $ROUNDS, $T6, L_enc_192
1015
1016    j L_fail_m2
1017.size rv64i_zvkned_encrypt,.-rv64i_zvkned_encrypt
1018___
1019
1020$code .= <<___;
1021.p2align 3
1022L_enc_128:
1023    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
1024
1025    @{[vle32_v $V1, $INP]}
1026
1027    @{[vle32_v $V10, $KEYP]}
1028    @{[vaesz_vs $V1, $V10]}    # with round key w[ 0, 3]
1029    addi $KEYP, $KEYP, 16
1030    @{[vle32_v $V11, $KEYP]}
1031    @{[vaesem_vs $V1, $V11]}   # with round key w[ 4, 7]
1032    addi $KEYP, $KEYP, 16
1033    @{[vle32_v $V12, $KEYP]}
1034    @{[vaesem_vs $V1, $V12]}   # with round key w[ 8,11]
1035    addi $KEYP, $KEYP, 16
1036    @{[vle32_v $V13, $KEYP]}
1037    @{[vaesem_vs $V1, $V13]}   # with round key w[12,15]
1038    addi $KEYP, $KEYP, 16
1039    @{[vle32_v $V14, $KEYP]}
1040    @{[vaesem_vs $V1, $V14]}   # with round key w[16,19]
1041    addi $KEYP, $KEYP, 16
1042    @{[vle32_v $V15, $KEYP]}
1043    @{[vaesem_vs $V1, $V15]}   # with round key w[20,23]
1044    addi $KEYP, $KEYP, 16
1045    @{[vle32_v $V16, $KEYP]}
1046    @{[vaesem_vs $V1, $V16]}   # with round key w[24,27]
1047    addi $KEYP, $KEYP, 16
1048    @{[vle32_v $V17, $KEYP]}
1049    @{[vaesem_vs $V1, $V17]}   # with round key w[28,31]
1050    addi $KEYP, $KEYP, 16
1051    @{[vle32_v $V18, $KEYP]}
1052    @{[vaesem_vs $V1, $V18]}   # with round key w[32,35]
1053    addi $KEYP, $KEYP, 16
1054    @{[vle32_v $V19, $KEYP]}
1055    @{[vaesem_vs $V1, $V19]}   # with round key w[36,39]
1056    addi $KEYP, $KEYP, 16
1057    @{[vle32_v $V20, $KEYP]}
1058    @{[vaesef_vs $V1, $V20]}   # with round key w[40,43]
1059
1060    @{[vse32_v $V1, $OUTP]}
1061
1062    ret
1063.size L_enc_128,.-L_enc_128
1064___
1065
1066$code .= <<___;
1067.p2align 3
1068L_enc_192:
1069    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
1070
1071    @{[vle32_v $V1, $INP]}
1072
1073    @{[vle32_v $V10, $KEYP]}
1074    @{[vaesz_vs $V1, $V10]}     # with round key w[ 0, 3]
1075    addi $KEYP, $KEYP, 16
1076    @{[vle32_v $V11, $KEYP]}
1077    @{[vaesem_vs $V1, $V11]}
1078    addi $KEYP, $KEYP, 16
1079    @{[vle32_v $V12, $KEYP]}
1080    @{[vaesem_vs $V1, $V12]}
1081    addi $KEYP, $KEYP, 16
1082    @{[vle32_v $V13, $KEYP]}
1083    @{[vaesem_vs $V1, $V13]}
1084    addi $KEYP, $KEYP, 16
1085    @{[vle32_v $V14, $KEYP]}
1086    @{[vaesem_vs $V1, $V14]}
1087    addi $KEYP, $KEYP, 16
1088    @{[vle32_v $V15, $KEYP]}
1089    @{[vaesem_vs $V1, $V15]}
1090    addi $KEYP, $KEYP, 16
1091    @{[vle32_v $V16, $KEYP]}
1092    @{[vaesem_vs $V1, $V16]}
1093    addi $KEYP, $KEYP, 16
1094    @{[vle32_v $V17, $KEYP]}
1095    @{[vaesem_vs $V1, $V17]}
1096    addi $KEYP, $KEYP, 16
1097    @{[vle32_v $V18, $KEYP]}
1098    @{[vaesem_vs $V1, $V18]}
1099    addi $KEYP, $KEYP, 16
1100    @{[vle32_v $V19, $KEYP]}
1101    @{[vaesem_vs $V1, $V19]}
1102    addi $KEYP, $KEYP, 16
1103    @{[vle32_v $V20, $KEYP]}
1104    @{[vaesem_vs $V1, $V20]}
1105    addi $KEYP, $KEYP, 16
1106    @{[vle32_v $V21, $KEYP]}
1107    @{[vaesem_vs $V1, $V21]}
1108    addi $KEYP, $KEYP, 16
1109    @{[vle32_v $V22, $KEYP]}
1110    @{[vaesef_vs $V1, $V22]}
1111
1112    @{[vse32_v $V1, $OUTP]}
1113    ret
1114.size L_enc_192,.-L_enc_192
1115___
1116
1117$code .= <<___;
1118.p2align 3
1119L_enc_256:
1120    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
1121
1122    @{[vle32_v $V1, $INP]}
1123
1124    @{[vle32_v $V10, $KEYP]}
1125    @{[vaesz_vs $V1, $V10]}     # with round key w[ 0, 3]
1126    addi $KEYP, $KEYP, 16
1127    @{[vle32_v $V11, $KEYP]}
1128    @{[vaesem_vs $V1, $V11]}
1129    addi $KEYP, $KEYP, 16
1130    @{[vle32_v $V12, $KEYP]}
1131    @{[vaesem_vs $V1, $V12]}
1132    addi $KEYP, $KEYP, 16
1133    @{[vle32_v $V13, $KEYP]}
1134    @{[vaesem_vs $V1, $V13]}
1135    addi $KEYP, $KEYP, 16
1136    @{[vle32_v $V14, $KEYP]}
1137    @{[vaesem_vs $V1, $V14]}
1138    addi $KEYP, $KEYP, 16
1139    @{[vle32_v $V15, $KEYP]}
1140    @{[vaesem_vs $V1, $V15]}
1141    addi $KEYP, $KEYP, 16
1142    @{[vle32_v $V16, $KEYP]}
1143    @{[vaesem_vs $V1, $V16]}
1144    addi $KEYP, $KEYP, 16
1145    @{[vle32_v $V17, $KEYP]}
1146    @{[vaesem_vs $V1, $V17]}
1147    addi $KEYP, $KEYP, 16
1148    @{[vle32_v $V18, $KEYP]}
1149    @{[vaesem_vs $V1, $V18]}
1150    addi $KEYP, $KEYP, 16
1151    @{[vle32_v $V19, $KEYP]}
1152    @{[vaesem_vs $V1, $V19]}
1153    addi $KEYP, $KEYP, 16
1154    @{[vle32_v $V20, $KEYP]}
1155    @{[vaesem_vs $V1, $V20]}
1156    addi $KEYP, $KEYP, 16
1157    @{[vle32_v $V21, $KEYP]}
1158    @{[vaesem_vs $V1, $V21]}
1159    addi $KEYP, $KEYP, 16
1160    @{[vle32_v $V22, $KEYP]}
1161    @{[vaesem_vs $V1, $V22]}
1162    addi $KEYP, $KEYP, 16
1163    @{[vle32_v $V23, $KEYP]}
1164    @{[vaesem_vs $V1, $V23]}
1165    addi $KEYP, $KEYP, 16
1166    @{[vle32_v $V24, $KEYP]}
1167    @{[vaesef_vs $V1, $V24]}
1168
1169    @{[vse32_v $V1, $OUTP]}
1170    ret
1171.size L_enc_256,.-L_enc_256
1172___
1173
1174################################################################################
1175# void rv64i_zvkned_decrypt(const unsigned char *in, unsigned char *out,
1176#                           const AES_KEY *key);
1177
1178$code .= <<___;
1179.p2align 3
1180.globl rv64i_zvkned_decrypt
1181.type rv64i_zvkned_decrypt,\@function
1182rv64i_zvkned_decrypt:
1183    # Load number of rounds
1184    lwu $ROUNDS, 240($KEYP)
1185
1186    # Get proper routine for key size
1187    li $T6, 14
1188    beq $ROUNDS, $T6, L_dec_256
1189    li $T6, 10
1190    beq $ROUNDS, $T6, L_dec_128
1191    li $T6, 12
1192    beq $ROUNDS, $T6, L_dec_192
1193
1194    j L_fail_m2
1195.size rv64i_zvkned_decrypt,.-rv64i_zvkned_decrypt
1196___
1197
1198$code .= <<___;
1199.p2align 3
1200L_dec_128:
1201    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
1202
1203    @{[vle32_v $V1, $INP]}
1204
1205    addi $KEYP, $KEYP, 160
1206    @{[vle32_v $V20, $KEYP]}
1207    @{[vaesz_vs $V1, $V20]}    # with round key w[40,43]
1208    addi $KEYP, $KEYP, -16
1209    @{[vle32_v $V19, $KEYP]}
1210    @{[vaesdm_vs $V1, $V19]}   # with round key w[36,39]
1211    addi $KEYP, $KEYP, -16
1212    @{[vle32_v $V18, $KEYP]}
1213    @{[vaesdm_vs $V1, $V18]}   # with round key w[32,35]
1214    addi $KEYP, $KEYP, -16
1215    @{[vle32_v $V17, $KEYP]}
1216    @{[vaesdm_vs $V1, $V17]}   # with round key w[28,31]
1217    addi $KEYP, $KEYP, -16
1218    @{[vle32_v $V16, $KEYP]}
1219    @{[vaesdm_vs $V1, $V16]}   # with round key w[24,27]
1220    addi $KEYP, $KEYP, -16
1221    @{[vle32_v $V15, $KEYP]}
1222    @{[vaesdm_vs $V1, $V15]}   # with round key w[20,23]
1223    addi $KEYP, $KEYP, -16
1224    @{[vle32_v $V14, $KEYP]}
1225    @{[vaesdm_vs $V1, $V14]}   # with round key w[16,19]
1226    addi $KEYP, $KEYP, -16
1227    @{[vle32_v $V13, $KEYP]}
1228    @{[vaesdm_vs $V1, $V13]}   # with round key w[12,15]
1229    addi $KEYP, $KEYP, -16
1230    @{[vle32_v $V12, $KEYP]}
1231    @{[vaesdm_vs $V1, $V12]}   # with round key w[ 8,11]
1232    addi $KEYP, $KEYP, -16
1233    @{[vle32_v $V11, $KEYP]}
1234    @{[vaesdm_vs $V1, $V11]}   # with round key w[ 4, 7]
1235    addi $KEYP, $KEYP, -16
1236    @{[vle32_v $V10, $KEYP]}
1237    @{[vaesdf_vs $V1, $V10]}   # with round key w[ 0, 3]
1238
1239    @{[vse32_v $V1, $OUTP]}
1240
1241    ret
1242.size L_dec_128,.-L_dec_128
1243___
1244
1245$code .= <<___;
1246.p2align 3
1247L_dec_192:
1248    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
1249
1250    @{[vle32_v $V1, $INP]}
1251
1252    addi $KEYP, $KEYP, 192
1253    @{[vle32_v $V22, $KEYP]}
1254    @{[vaesz_vs $V1, $V22]}    # with round key w[48,51]
1255    addi $KEYP, $KEYP, -16
1256    @{[vle32_v $V21, $KEYP]}
1257    @{[vaesdm_vs $V1, $V21]}   # with round key w[44,47]
1258    addi $KEYP, $KEYP, -16
1259    @{[vle32_v $V20, $KEYP]}
1260    @{[vaesdm_vs $V1, $V20]}    # with round key w[40,43]
1261    addi $KEYP, $KEYP, -16
1262    @{[vle32_v $V19, $KEYP]}
1263    @{[vaesdm_vs $V1, $V19]}   # with round key w[36,39]
1264    addi $KEYP, $KEYP, -16
1265    @{[vle32_v $V18, $KEYP]}
1266    @{[vaesdm_vs $V1, $V18]}   # with round key w[32,35]
1267    addi $KEYP, $KEYP, -16
1268    @{[vle32_v $V17, $KEYP]}
1269    @{[vaesdm_vs $V1, $V17]}   # with round key w[28,31]
1270    addi $KEYP, $KEYP, -16
1271    @{[vle32_v $V16, $KEYP]}
1272    @{[vaesdm_vs $V1, $V16]}   # with round key w[24,27]
1273    addi $KEYP, $KEYP, -16
1274    @{[vle32_v $V15, $KEYP]}
1275    @{[vaesdm_vs $V1, $V15]}   # with round key w[20,23]
1276    addi $KEYP, $KEYP, -16
1277    @{[vle32_v $V14, $KEYP]}
1278    @{[vaesdm_vs $V1, $V14]}   # with round key w[16,19]
1279    addi $KEYP, $KEYP, -16
1280    @{[vle32_v $V13, $KEYP]}
1281    @{[vaesdm_vs $V1, $V13]}   # with round key w[12,15]
1282    addi $KEYP, $KEYP, -16
1283    @{[vle32_v $V12, $KEYP]}
1284    @{[vaesdm_vs $V1, $V12]}   # with round key w[ 8,11]
1285    addi $KEYP, $KEYP, -16
1286    @{[vle32_v $V11, $KEYP]}
1287    @{[vaesdm_vs $V1, $V11]}   # with round key w[ 4, 7]
1288    addi $KEYP, $KEYP, -16
1289    @{[vle32_v $V10, $KEYP]}
1290    @{[vaesdf_vs $V1, $V10]}   # with round key w[ 0, 3]
1291
1292    @{[vse32_v $V1, $OUTP]}
1293
1294    ret
1295.size L_dec_192,.-L_dec_192
1296___
1297
1298$code .= <<___;
1299.p2align 3
1300L_dec_256:
1301    @{[vsetivli "zero", 4, "e32", "m1", "ta", "ma"]}
1302
1303    @{[vle32_v $V1, $INP]}
1304
1305    addi $KEYP, $KEYP, 224
1306    @{[vle32_v $V24, $KEYP]}
1307    @{[vaesz_vs $V1, $V24]}    # with round key w[56,59]
1308    addi $KEYP, $KEYP, -16
1309    @{[vle32_v $V23, $KEYP]}
1310    @{[vaesdm_vs $V1, $V23]}   # with round key w[52,55]
1311    addi $KEYP, $KEYP, -16
1312    @{[vle32_v $V22, $KEYP]}
1313    @{[vaesdm_vs $V1, $V22]}    # with round key w[48,51]
1314    addi $KEYP, $KEYP, -16
1315    @{[vle32_v $V21, $KEYP]}
1316    @{[vaesdm_vs $V1, $V21]}   # with round key w[44,47]
1317    addi $KEYP, $KEYP, -16
1318    @{[vle32_v $V20, $KEYP]}
1319    @{[vaesdm_vs $V1, $V20]}    # with round key w[40,43]
1320    addi $KEYP, $KEYP, -16
1321    @{[vle32_v $V19, $KEYP]}
1322    @{[vaesdm_vs $V1, $V19]}   # with round key w[36,39]
1323    addi $KEYP, $KEYP, -16
1324    @{[vle32_v $V18, $KEYP]}
1325    @{[vaesdm_vs $V1, $V18]}   # with round key w[32,35]
1326    addi $KEYP, $KEYP, -16
1327    @{[vle32_v $V17, $KEYP]}
1328    @{[vaesdm_vs $V1, $V17]}   # with round key w[28,31]
1329    addi $KEYP, $KEYP, -16
1330    @{[vle32_v $V16, $KEYP]}
1331    @{[vaesdm_vs $V1, $V16]}   # with round key w[24,27]
1332    addi $KEYP, $KEYP, -16
1333    @{[vle32_v $V15, $KEYP]}
1334    @{[vaesdm_vs $V1, $V15]}   # with round key w[20,23]
1335    addi $KEYP, $KEYP, -16
1336    @{[vle32_v $V14, $KEYP]}
1337    @{[vaesdm_vs $V1, $V14]}   # with round key w[16,19]
1338    addi $KEYP, $KEYP, -16
1339    @{[vle32_v $V13, $KEYP]}
1340    @{[vaesdm_vs $V1, $V13]}   # with round key w[12,15]
1341    addi $KEYP, $KEYP, -16
1342    @{[vle32_v $V12, $KEYP]}
1343    @{[vaesdm_vs $V1, $V12]}   # with round key w[ 8,11]
1344    addi $KEYP, $KEYP, -16
1345    @{[vle32_v $V11, $KEYP]}
1346    @{[vaesdm_vs $V1, $V11]}   # with round key w[ 4, 7]
1347    addi $KEYP, $KEYP, -16
1348    @{[vle32_v $V10, $KEYP]}
1349    @{[vaesdf_vs $V1, $V10]}   # with round key w[ 0, 3]
1350
1351    @{[vse32_v $V1, $OUTP]}
1352
1353    ret
1354.size L_dec_256,.-L_dec_256
1355___
1356}
1357
1358$code .= <<___;
1359L_fail_m1:
1360    li a0, -1
1361    ret
1362.size L_fail_m1,.-L_fail_m1
1363
1364L_fail_m2:
1365    li a0, -2
1366    ret
1367.size L_fail_m2,.-L_fail_m2
1368
1369L_end:
1370  ret
1371.size L_end,.-L_end
1372___
1373
1374print $code;
1375
1376close STDOUT or die "error closing STDOUT: $!";
1377