~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/riscv/crypto/aes-riscv64-zvkned.S

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
  2 //
  3 // This file is dual-licensed, meaning that you can use it under your
  4 // choice of either of the following two licenses:
  5 //
  6 // Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
  7 //
  8 // Licensed under the Apache License 2.0 (the "License"). You can obtain
  9 // a copy in the file LICENSE in the source distribution or at
 10 // https://www.openssl.org/source/license.html
 11 //
 12 // or
 13 //
 14 // Copyright (c) 2023, Christoph Müllner <christoph.muellner@vrull.eu>
 15 // Copyright (c) 2023, Phoebe Chen <phoebe.chen@sifive.com>
 16 // Copyright (c) 2023, Jerry Shih <jerry.shih@sifive.com>
 17 // Copyright 2024 Google LLC
 18 // All rights reserved.
 19 //
 20 // Redistribution and use in source and binary forms, with or without
 21 // modification, are permitted provided that the following conditions
 22 // are met:
 23 // 1. Redistributions of source code must retain the above copyright
 24 //    notice, this list of conditions and the following disclaimer.
 25 // 2. Redistributions in binary form must reproduce the above copyright
 26 //    notice, this list of conditions and the following disclaimer in the
 27 //    documentation and/or other materials provided with the distribution.
 28 //
 29 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 30 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 31 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 32 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 33 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 34 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 35 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 36 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 37 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 38 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 39 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 40 
 41 // The generated code of this file depends on the following RISC-V extensions:
 42 // - RV64I
 43 // - RISC-V Vector ('V') with VLEN >= 128
 44 // - RISC-V Vector AES block cipher extension ('Zvkned')
 45 
 46 #include <linux/linkage.h>
 47 
 48 .text
 49 .option arch, +zvkned
 50 
 51 #include "aes-macros.S"
 52 
 53 #define KEYP            a0
 54 #define INP             a1
 55 #define OUTP            a2
 56 #define LEN             a3
 57 #define IVP             a4
 58 
 59 .macro  __aes_crypt_zvkned      enc, keylen
 60         vle32.v         v16, (INP)
 61         aes_crypt       v16, \enc, \keylen
 62         vse32.v         v16, (OUTP)
 63         ret
 64 .endm
 65 
 66 .macro  aes_crypt_zvkned        enc
 67         aes_begin       KEYP, 128f, 192f
 68         __aes_crypt_zvkned      \enc, 256
 69 128:
 70         __aes_crypt_zvkned      \enc, 128
 71 192:
 72         __aes_crypt_zvkned      \enc, 192
 73 .endm
 74 
 75 // void aes_encrypt_zvkned(const struct crypto_aes_ctx *key,
 76 //                         const u8 in[16], u8 out[16]);
 77 SYM_FUNC_START(aes_encrypt_zvkned)
 78         aes_crypt_zvkned        1
 79 SYM_FUNC_END(aes_encrypt_zvkned)
 80 
 81 // Same prototype and calling convention as the encryption function
 82 SYM_FUNC_START(aes_decrypt_zvkned)
 83         aes_crypt_zvkned        0
 84 SYM_FUNC_END(aes_decrypt_zvkned)
 85 
 86 .macro  __aes_ecb_crypt enc, keylen
 87         srli            t0, LEN, 2
 88         // t0 is the remaining length in 32-bit words.  It's a multiple of 4.
 89 1:
 90         vsetvli         t1, t0, e32, m8, ta, ma
 91         sub             t0, t0, t1      // Subtract number of words processed
 92         slli            t1, t1, 2       // Words to bytes
 93         vle32.v         v16, (INP)
 94         aes_crypt       v16, \enc, \keylen
 95         vse32.v         v16, (OUTP)
 96         add             INP, INP, t1
 97         add             OUTP, OUTP, t1
 98         bnez            t0, 1b
 99 
100         ret
101 .endm
102 
103 .macro  aes_ecb_crypt   enc
104         aes_begin       KEYP, 128f, 192f
105         __aes_ecb_crypt \enc, 256
106 128:
107         __aes_ecb_crypt \enc, 128
108 192:
109         __aes_ecb_crypt \enc, 192
110 .endm
111 
112 // void aes_ecb_encrypt_zvkned(const struct crypto_aes_ctx *key,
113 //                             const u8 *in, u8 *out, size_t len);
114 //
115 // |len| must be nonzero and a multiple of 16 (AES_BLOCK_SIZE).
116 SYM_FUNC_START(aes_ecb_encrypt_zvkned)
117         aes_ecb_crypt   1
118 SYM_FUNC_END(aes_ecb_encrypt_zvkned)
119 
120 // Same prototype and calling convention as the encryption function
121 SYM_FUNC_START(aes_ecb_decrypt_zvkned)
122         aes_ecb_crypt   0
123 SYM_FUNC_END(aes_ecb_decrypt_zvkned)
124 
125 .macro  aes_cbc_encrypt keylen
126         vle32.v         v16, (IVP)      // Load IV
127 1:
128         vle32.v         v17, (INP)      // Load plaintext block
129         vxor.vv         v16, v16, v17   // XOR with IV or prev ciphertext block
130         aes_encrypt     v16, \keylen    // Encrypt
131         vse32.v         v16, (OUTP)     // Store ciphertext block
132         addi            INP, INP, 16
133         addi            OUTP, OUTP, 16
134         addi            LEN, LEN, -16
135         bnez            LEN, 1b
136 
137         vse32.v         v16, (IVP)      // Store next IV
138         ret
139 .endm
140 
141 .macro  aes_cbc_decrypt keylen
142         srli            LEN, LEN, 2     // Convert LEN from bytes to words
143         vle32.v         v16, (IVP)      // Load IV
144 1:
145         vsetvli         t0, LEN, e32, m4, ta, ma
146         vle32.v         v20, (INP)      // Load ciphertext blocks
147         vslideup.vi     v16, v20, 4     // Setup prev ciphertext blocks
148         addi            t1, t0, -4
149         vslidedown.vx   v24, v20, t1    // Save last ciphertext block
150         aes_decrypt     v20, \keylen    // Decrypt the blocks
151         vxor.vv         v20, v20, v16   // XOR with prev ciphertext blocks
152         vse32.v         v20, (OUTP)     // Store plaintext blocks
153         vmv.v.v         v16, v24        // Next "IV" is last ciphertext block
154         slli            t1, t0, 2       // Words to bytes
155         add             INP, INP, t1
156         add             OUTP, OUTP, t1
157         sub             LEN, LEN, t0
158         bnez            LEN, 1b
159 
160         vsetivli        zero, 4, e32, m1, ta, ma
161         vse32.v         v16, (IVP)      // Store next IV
162         ret
163 .endm
164 
165 // void aes_cbc_encrypt_zvkned(const struct crypto_aes_ctx *key,
166 //                             const u8 *in, u8 *out, size_t len, u8 iv[16]);
167 //
168 // |len| must be nonzero and a multiple of 16 (AES_BLOCK_SIZE).
169 SYM_FUNC_START(aes_cbc_encrypt_zvkned)
170         aes_begin       KEYP, 128f, 192f
171         aes_cbc_encrypt 256
172 128:
173         aes_cbc_encrypt 128
174 192:
175         aes_cbc_encrypt 192
176 SYM_FUNC_END(aes_cbc_encrypt_zvkned)
177 
178 // Same prototype and calling convention as the encryption function
179 SYM_FUNC_START(aes_cbc_decrypt_zvkned)
180         aes_begin       KEYP, 128f, 192f
181         aes_cbc_decrypt 256
182 128:
183         aes_cbc_decrypt 128
184 192:
185         aes_cbc_decrypt 192
186 SYM_FUNC_END(aes_cbc_decrypt_zvkned)
187 
188 .macro  aes_cbc_cts_encrypt     keylen
189 
190         // CBC-encrypt all blocks except the last.  But don't store the
191         // second-to-last block to the output buffer yet, since it will be
192         // handled specially in the ciphertext stealing step.  Exception: if the
193         // message is single-block, still encrypt the last (and only) block.
194         li              t0, 16
195         j               2f
196 1:
197         vse32.v         v16, (OUTP)     // Store ciphertext block
198         addi            OUTP, OUTP, 16
199 2:
200         vle32.v         v17, (INP)      // Load plaintext block
201         vxor.vv         v16, v16, v17   // XOR with IV or prev ciphertext block
202         aes_encrypt     v16, \keylen    // Encrypt
203         addi            INP, INP, 16
204         addi            LEN, LEN, -16
205         bgt             LEN, t0, 1b     // Repeat if more than one block remains
206 
207         // Special case: if the message is a single block, just do CBC.
208         beqz            LEN, .Lcts_encrypt_done\@
209 
210         // Encrypt the last two blocks using ciphertext stealing as follows:
211         //      C[n-1] = Encrypt(Encrypt(P[n-1] ^ C[n-2]) ^ P[n])
212         //      C[n] = Encrypt(P[n-1] ^ C[n-2])[0..LEN]
213         //
214         // C[i] denotes the i'th ciphertext block, and likewise P[i] the i'th
215         // plaintext block.  Block n, the last block, may be partial; its length
216         // is 1 <= LEN <= 16.  If there are only 2 blocks, C[n-2] means the IV.
217         //
218         // v16 already contains Encrypt(P[n-1] ^ C[n-2]).
219         // INP points to P[n].  OUTP points to where C[n-1] should go.
220         // To support in-place encryption, load P[n] before storing C[n].
221         addi            t0, OUTP, 16    // Get pointer to where C[n] should go
222         vsetvli         zero, LEN, e8, m1, tu, ma
223         vle8.v          v17, (INP)      // Load P[n]
224         vse8.v          v16, (t0)       // Store C[n]
225         vxor.vv         v16, v16, v17   // v16 = Encrypt(P[n-1] ^ C[n-2]) ^ P[n]
226         vsetivli        zero, 4, e32, m1, ta, ma
227         aes_encrypt     v16, \keylen
228 .Lcts_encrypt_done\@:
229         vse32.v         v16, (OUTP)     // Store C[n-1] (or C[n] in single-block case)
230         ret
231 .endm
232 
233 #define LEN32           t4 // Length of remaining full blocks in 32-bit words
234 #define LEN_MOD16       t5 // Length of message in bytes mod 16
235 
236 .macro  aes_cbc_cts_decrypt     keylen
237         andi            LEN32, LEN, ~15
238         srli            LEN32, LEN32, 2
239         andi            LEN_MOD16, LEN, 15
240 
241         // Save C[n-2] in v28 so that it's available later during the ciphertext
242         // stealing step.  If there are fewer than three blocks, C[n-2] means
243         // the IV, otherwise it means the third-to-last ciphertext block.
244         vmv.v.v         v28, v16        // IV
245         add             t0, LEN, -33
246         bltz            t0, .Lcts_decrypt_loop\@
247         andi            t0, t0, ~15
248         add             t0, t0, INP
249         vle32.v         v28, (t0)
250 
251         // CBC-decrypt all full blocks.  For the last full block, or the last 2
252         // full blocks if the message is block-aligned, this doesn't write the
253         // correct output blocks (unless the message is only a single block),
254         // because it XORs the wrong values with the raw AES plaintexts.  But we
255         // fix this after this loop without redoing the AES decryptions.  This
256         // approach allows more of the AES decryptions to be parallelized.
257 .Lcts_decrypt_loop\@:
258         vsetvli         t0, LEN32, e32, m4, ta, ma
259         addi            t1, t0, -4
260         vle32.v         v20, (INP)      // Load next set of ciphertext blocks
261         vmv.v.v         v24, v16        // Get IV or last ciphertext block of prev set
262         vslideup.vi     v24, v20, 4     // Setup prev ciphertext blocks
263         vslidedown.vx   v16, v20, t1    // Save last ciphertext block of this set
264         aes_decrypt     v20, \keylen    // Decrypt this set of blocks
265         vxor.vv         v24, v24, v20   // XOR prev ciphertext blocks with decrypted blocks
266         vse32.v         v24, (OUTP)     // Store this set of plaintext blocks
267         sub             LEN32, LEN32, t0
268         slli            t0, t0, 2       // Words to bytes
269         add             INP, INP, t0
270         add             OUTP, OUTP, t0
271         bnez            LEN32, .Lcts_decrypt_loop\@
272 
273         vsetivli        zero, 4, e32, m4, ta, ma
274         vslidedown.vx   v20, v20, t1    // Extract raw plaintext of last full block
275         addi            t0, OUTP, -16   // Get pointer to last full plaintext block
276         bnez            LEN_MOD16, .Lcts_decrypt_non_block_aligned\@
277 
278         // Special case: if the message is a single block, just do CBC.
279         li              t1, 16
280         beq             LEN, t1, .Lcts_decrypt_done\@
281 
282         // Block-aligned message.  Just fix up the last 2 blocks.  We need:
283         //
284         //      P[n-1] = Decrypt(C[n]) ^ C[n-2]
285         //      P[n] = Decrypt(C[n-1]) ^ C[n]
286         //
287         // We have C[n] in v16, Decrypt(C[n]) in v20, and C[n-2] in v28.
288         // Together with Decrypt(C[n-1]) ^ C[n-2] from the output buffer, this
289         // is everything needed to fix the output without re-decrypting blocks.
290         addi            t1, OUTP, -32   // Get pointer to where P[n-1] should go
291         vxor.vv         v20, v20, v28   // Decrypt(C[n]) ^ C[n-2] == P[n-1]
292         vle32.v         v24, (t1)       // Decrypt(C[n-1]) ^ C[n-2]
293         vse32.v         v20, (t1)       // Store P[n-1]
294         vxor.vv         v20, v24, v16   // Decrypt(C[n-1]) ^ C[n-2] ^ C[n] == P[n] ^ C[n-2]
295         j               .Lcts_decrypt_finish\@
296 
297 .Lcts_decrypt_non_block_aligned\@:
298         // Decrypt the last two blocks using ciphertext stealing as follows:
299         //
300         //      P[n-1] = Decrypt(C[n] || Decrypt(C[n-1])[LEN_MOD16..16]) ^ C[n-2]
301         //      P[n] = (Decrypt(C[n-1]) ^ C[n])[0..LEN_MOD16]
302         //
303         // We already have Decrypt(C[n-1]) in v20 and C[n-2] in v28.
304         vmv.v.v         v16, v20        // v16 = Decrypt(C[n-1])
305         vsetvli         zero, LEN_MOD16, e8, m1, tu, ma
306         vle8.v          v20, (INP)      // v20 = C[n] || Decrypt(C[n-1])[LEN_MOD16..16]
307         vxor.vv         v16, v16, v20   // v16 = Decrypt(C[n-1]) ^ C[n]
308         vse8.v          v16, (OUTP)     // Store P[n]
309         vsetivli        zero, 4, e32, m1, ta, ma
310         aes_decrypt     v20, \keylen    // v20 = Decrypt(C[n] || Decrypt(C[n-1])[LEN_MOD16..16])
311 .Lcts_decrypt_finish\@:
312         vxor.vv         v20, v20, v28   // XOR with C[n-2]
313         vse32.v         v20, (t0)       // Store last full plaintext block
314 .Lcts_decrypt_done\@:
315         ret
316 .endm
317 
318 .macro  aes_cbc_cts_crypt       keylen
319         vle32.v         v16, (IVP)      // Load IV
320         beqz            a5, .Lcts_decrypt\@
321         aes_cbc_cts_encrypt \keylen
322 .Lcts_decrypt\@:
323         aes_cbc_cts_decrypt \keylen
324 .endm
325 
326 // void aes_cbc_cts_crypt_zvkned(const struct crypto_aes_ctx *key,
327 //                               const u8 *in, u8 *out, size_t len,
328 //                               const u8 iv[16], bool enc);
329 //
330 // Encrypts or decrypts a message with the CS3 variant of AES-CBC-CTS.
331 // This is the variant that unconditionally swaps the last two blocks.
332 SYM_FUNC_START(aes_cbc_cts_crypt_zvkned)
333         aes_begin       KEYP, 128f, 192f
334         aes_cbc_cts_crypt 256
335 128:
336         aes_cbc_cts_crypt 128
337 192:
338         aes_cbc_cts_crypt 192
339 SYM_FUNC_END(aes_cbc_cts_crypt_zvkned)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php