28
28
#include <asm/neon.h>
29
29
#include <asm/simd.h>
30
30
31
- asmlinkage void chacha20_block_xor_neon (u32 * state , u8 * dst , const u8 * src );
32
- asmlinkage void chacha20_4block_xor_neon (u32 * state , u8 * dst , const u8 * src );
33
- asmlinkage void hchacha20_block_neon (const u32 * state , u32 * out );
34
-
35
- static void chacha20_doneon (u32 * state , u8 * dst , const u8 * src ,
36
- unsigned int bytes )
31
+ asmlinkage void chacha_block_xor_neon (const u32 * state , u8 * dst , const u8 * src ,
32
+ int nrounds );
33
+ asmlinkage void chacha_4block_xor_neon (const u32 * state , u8 * dst , const u8 * src ,
34
+ int nrounds );
35
+ asmlinkage void hchacha_block_neon (const u32 * state , u32 * out , int nrounds );
36
+
37
+ static void chacha_doneon (u32 * state , u8 * dst , const u8 * src ,
38
+ unsigned int bytes , int nrounds )
37
39
{
38
40
u8 buf [CHACHA_BLOCK_SIZE ];
39
41
40
42
while (bytes >= CHACHA_BLOCK_SIZE * 4 ) {
41
- chacha20_4block_xor_neon (state , dst , src );
43
+ chacha_4block_xor_neon (state , dst , src , nrounds );
42
44
bytes -= CHACHA_BLOCK_SIZE * 4 ;
43
45
src += CHACHA_BLOCK_SIZE * 4 ;
44
46
dst += CHACHA_BLOCK_SIZE * 4 ;
45
47
state [12 ] += 4 ;
46
48
}
47
49
while (bytes >= CHACHA_BLOCK_SIZE ) {
48
- chacha20_block_xor_neon (state , dst , src );
50
+ chacha_block_xor_neon (state , dst , src , nrounds );
49
51
bytes -= CHACHA_BLOCK_SIZE ;
50
52
src += CHACHA_BLOCK_SIZE ;
51
53
dst += CHACHA_BLOCK_SIZE ;
52
54
state [12 ]++ ;
53
55
}
54
56
if (bytes ) {
55
57
memcpy (buf , src , bytes );
56
- chacha20_block_xor_neon (state , buf , buf );
58
+ chacha_block_xor_neon (state , buf , buf , nrounds );
57
59
memcpy (dst , buf , bytes );
58
60
}
59
61
}
60
62
61
- static int chacha20_neon_stream_xor (struct skcipher_request * req ,
62
- struct chacha_ctx * ctx , u8 * iv )
63
+ static int chacha_neon_stream_xor (struct skcipher_request * req ,
64
+ struct chacha_ctx * ctx , u8 * iv )
63
65
{
64
66
struct skcipher_walk walk ;
65
67
u32 state [16 ];
@@ -76,27 +78,27 @@ static int chacha20_neon_stream_xor(struct skcipher_request *req,
76
78
nbytes = round_down (nbytes , walk .stride );
77
79
78
80
kernel_neon_begin ();
79
- chacha20_doneon (state , walk .dst .virt .addr , walk .src .virt .addr ,
80
- nbytes );
81
+ chacha_doneon (state , walk .dst .virt .addr , walk .src .virt .addr ,
82
+ nbytes , ctx -> nrounds );
81
83
kernel_neon_end ();
82
84
err = skcipher_walk_done (& walk , walk .nbytes - nbytes );
83
85
}
84
86
85
87
return err ;
86
88
}
87
89
88
- static int chacha20_neon (struct skcipher_request * req )
90
+ static int chacha_neon (struct skcipher_request * req )
89
91
{
90
92
struct crypto_skcipher * tfm = crypto_skcipher_reqtfm (req );
91
93
struct chacha_ctx * ctx = crypto_skcipher_ctx (tfm );
92
94
93
95
if (req -> cryptlen <= CHACHA_BLOCK_SIZE || !may_use_simd ())
94
96
return crypto_chacha_crypt (req );
95
97
96
- return chacha20_neon_stream_xor (req , ctx , req -> iv );
98
+ return chacha_neon_stream_xor (req , ctx , req -> iv );
97
99
}
98
100
99
- static int xchacha20_neon (struct skcipher_request * req )
101
+ static int xchacha_neon (struct skcipher_request * req )
100
102
{
101
103
struct crypto_skcipher * tfm = crypto_skcipher_reqtfm (req );
102
104
struct chacha_ctx * ctx = crypto_skcipher_ctx (tfm );
@@ -110,12 +112,13 @@ static int xchacha20_neon(struct skcipher_request *req)
110
112
crypto_chacha_init (state , ctx , req -> iv );
111
113
112
114
kernel_neon_begin ();
113
- hchacha20_block_neon (state , subctx .key );
115
+ hchacha_block_neon (state , subctx .key , ctx -> nrounds );
114
116
kernel_neon_end ();
117
+ subctx .nrounds = ctx -> nrounds ;
115
118
116
119
memcpy (& real_iv [0 ], req -> iv + 24 , 8 );
117
120
memcpy (& real_iv [8 ], req -> iv + 16 , 8 );
118
- return chacha20_neon_stream_xor (req , & subctx , real_iv );
121
+ return chacha_neon_stream_xor (req , & subctx , real_iv );
119
122
}
120
123
121
124
static struct skcipher_alg algs [] = {
@@ -133,8 +136,8 @@ static struct skcipher_alg algs[] = {
133
136
.chunksize = CHACHA_BLOCK_SIZE ,
134
137
.walksize = 4 * CHACHA_BLOCK_SIZE ,
135
138
.setkey = crypto_chacha20_setkey ,
136
- .encrypt = chacha20_neon ,
137
- .decrypt = chacha20_neon ,
139
+ .encrypt = chacha_neon ,
140
+ .decrypt = chacha_neon ,
138
141
}, {
139
142
.base .cra_name = "xchacha20" ,
140
143
.base .cra_driver_name = "xchacha20-neon" ,
@@ -149,27 +152,28 @@ static struct skcipher_alg algs[] = {
149
152
.chunksize = CHACHA_BLOCK_SIZE ,
150
153
.walksize = 4 * CHACHA_BLOCK_SIZE ,
151
154
.setkey = crypto_chacha20_setkey ,
152
- .encrypt = xchacha20_neon ,
153
- .decrypt = xchacha20_neon ,
155
+ .encrypt = xchacha_neon ,
156
+ .decrypt = xchacha_neon ,
154
157
}
155
158
};
156
159
157
- static int __init chacha20_simd_mod_init (void )
160
+ static int __init chacha_simd_mod_init (void )
158
161
{
159
162
if (!(elf_hwcap & HWCAP_NEON ))
160
163
return - ENODEV ;
161
164
162
165
return crypto_register_skciphers (algs , ARRAY_SIZE (algs ));
163
166
}
164
167
165
- static void __exit chacha20_simd_mod_fini (void )
168
+ static void __exit chacha_simd_mod_fini (void )
166
169
{
167
170
crypto_unregister_skciphers (algs , ARRAY_SIZE (algs ));
168
171
}
169
172
170
- module_init (chacha20_simd_mod_init );
171
- module_exit (chacha20_simd_mod_fini );
173
+ module_init (chacha_simd_mod_init );
174
+ module_exit (chacha_simd_mod_fini );
172
175
176
+ MODULE_DESCRIPTION ("ChaCha and XChaCha stream ciphers (NEON accelerated)" );
173
177
MODULE_AUTHOR ("Ard Biesheuvel <ard.biesheuvel@linaro.org>" );
174
178
MODULE_LICENSE ("GPL v2" );
175
179
MODULE_ALIAS_CRYPTO ("chacha20" );
0 commit comments