1
- // Copyright 2015-2016 Brian Smith.
1
+ // Copyright 2015-2025 Brian Smith.
2
2
//
3
3
// Permission to use, copy, modify, and/or distribute this software for any
4
4
// purpose with or without fee is hereby granted, provided that the above
@@ -25,9 +25,6 @@ use crate::{
25
25
} ;
26
26
use core:: ops:: RangeFrom ;
27
27
28
- #[ cfg( target_arch = "x86_64" ) ]
29
- use aes:: EncryptCtr32 as _;
30
-
31
28
#[ cfg( any(
32
29
all( target_arch = "aarch64" , target_endian = "little" ) ,
33
30
all( target_arch = "arm" , target_endian = "little" ) ,
@@ -36,6 +33,8 @@ use aes::EncryptCtr32 as _;
36
33
) ) ]
37
34
use cpu:: GetFeature as _;
38
35
36
+ mod aeshwclmulmovbe;
37
+
39
38
#[ derive( Clone ) ]
40
39
pub ( super ) struct Key ( DynKey ) ;
41
40
@@ -178,47 +177,7 @@ pub(super) fn seal(
178
177
match key {
179
178
#[ cfg( target_arch = "x86_64" ) ]
180
179
DynKey :: AesHwClMulAvxMovbe ( Combo { aes_key, gcm_key } ) => {
181
- use crate :: c;
182
- let mut auth = gcm:: Context :: new ( gcm_key, aad, in_out. len ( ) ) ?;
183
- let ( htable, xi) = auth. inner ( ) ;
184
- prefixed_extern ! {
185
- // `HTable` and `Xi` should be 128-bit aligned. TODO: Can we shrink `HTable`? The
186
- // assembly says it needs just nine values in that array.
187
- fn aesni_gcm_encrypt(
188
- input: * const u8 ,
189
- output: * mut u8 ,
190
- len: c:: size_t,
191
- key: & aes:: AES_KEY ,
192
- ivec: & mut Counter ,
193
- Htable : & gcm:: HTable ,
194
- Xi : & mut gcm:: Xi ) -> c:: size_t;
195
- }
196
- let processed = unsafe {
197
- aesni_gcm_encrypt (
198
- in_out. as_ptr ( ) ,
199
- in_out. as_mut_ptr ( ) ,
200
- in_out. len ( ) ,
201
- aes_key. inner_less_safe ( ) ,
202
- & mut ctr,
203
- htable,
204
- xi,
205
- )
206
- } ;
207
-
208
- let ramaining = match in_out. get_mut ( processed..) {
209
- Some ( remaining) => remaining,
210
- None => {
211
- // This can't happen. If it did, then the assembly already
212
- // caused a buffer overflow.
213
- unreachable ! ( )
214
- }
215
- } ;
216
- let ( mut whole, remainder) = slice:: as_chunks_mut ( ramaining) ;
217
- aes_key. ctr32_encrypt_within ( whole. as_flattened_mut ( ) . into ( ) , & mut ctr) ;
218
- auth. update_blocks ( whole. as_ref ( ) ) ;
219
- let remainder = OverlappingPartialBlock :: new ( remainder. into ( ) )
220
- . unwrap_or_else ( |InputTooLongError { .. } | unreachable ! ( ) ) ;
221
- seal_finish ( aes_key, auth, remainder, ctr, tag_iv)
180
+ aeshwclmulmovbe:: seal ( aes_key, gcm_key, ctr, tag_iv, aad, in_out)
222
181
}
223
182
224
183
#[ cfg( all( target_arch = "aarch64" , target_endian = "little" ) ) ]
@@ -344,86 +303,21 @@ pub(super) fn open(
344
303
in_out_slice : & mut [ u8 ] ,
345
304
src : RangeFrom < usize > ,
346
305
) -> Result < Tag , error:: Unspecified > {
347
- #[ cfg( any(
348
- all( target_arch = "aarch64" , target_endian = "little" ) ,
349
- target_arch = "x86_64"
350
- ) ) ]
351
- let in_out = Overlapping :: new ( in_out_slice, src. clone ( ) ) . map_err ( error:: erase :: < IndexError > ) ?;
352
-
353
306
let mut ctr = Counter :: one ( nonce) ;
354
307
let tag_iv = ctr. increment ( ) ;
355
308
356
309
match key {
357
310
#[ cfg( target_arch = "x86_64" ) ]
358
311
DynKey :: AesHwClMulAvxMovbe ( Combo { aes_key, gcm_key } ) => {
359
- use crate :: c;
360
-
361
- prefixed_extern ! {
362
- // `HTable` and `Xi` should be 128-bit aligned. TODO: Can we shrink `HTable`? The
363
- // assembly says it needs just nine values in that array.
364
- fn aesni_gcm_decrypt(
365
- input: * const u8 ,
366
- output: * mut u8 ,
367
- len: c:: size_t,
368
- key: & aes:: AES_KEY ,
369
- ivec: & mut Counter ,
370
- Htable : & gcm:: HTable ,
371
- Xi : & mut gcm:: Xi ) -> c:: size_t;
372
- }
373
-
374
- let mut auth = gcm:: Context :: new ( gcm_key, aad, in_out. len ( ) ) ?;
375
- let processed = in_out. with_input_output_len ( |input, output, len| {
376
- let ( htable, xi) = auth. inner ( ) ;
377
- unsafe {
378
- aesni_gcm_decrypt (
379
- input,
380
- output,
381
- len,
382
- aes_key. inner_less_safe ( ) ,
383
- & mut ctr,
384
- htable,
385
- xi,
386
- )
387
- }
388
- } ) ;
389
- let in_out_slice = in_out_slice. get_mut ( processed..) . unwrap_or_else ( || {
390
- // This can't happen. If it did, then the assembly already
391
- // caused a buffer overflow.
392
- unreachable ! ( )
393
- } ) ;
394
- // Authenticate any remaining whole blocks.
395
- let in_out = Overlapping :: new ( in_out_slice, src. clone ( ) ) . unwrap_or_else (
396
- |IndexError { .. } | {
397
- // This can't happen. If it did, then the assembly already
398
- // overwrote part of the remaining input.
399
- unreachable ! ( )
400
- } ,
401
- ) ;
402
- let ( whole, _) = slice:: as_chunks ( in_out. input ( ) ) ;
403
- auth. update_blocks ( whole) ;
404
-
405
- let whole_len = whole. as_flattened ( ) . len ( ) ;
406
-
407
- // Decrypt any remaining whole blocks.
408
- let whole = Overlapping :: new ( & mut in_out_slice[ ..( src. start + whole_len) ] , src. clone ( ) )
409
- . map_err ( error:: erase :: < IndexError > ) ?;
410
- aes_key. ctr32_encrypt_within ( whole, & mut ctr) ;
411
-
412
- let in_out_slice = match in_out_slice. get_mut ( whole_len..) {
413
- Some ( partial) => partial,
414
- None => unreachable ! ( ) ,
415
- } ;
416
- let in_out = Overlapping :: new ( in_out_slice, src)
417
- . unwrap_or_else ( |IndexError { .. } | unreachable ! ( ) ) ;
418
- let in_out = OverlappingPartialBlock :: new ( in_out)
419
- . unwrap_or_else ( |InputTooLongError { .. } | unreachable ! ( ) ) ;
420
- open_finish ( aes_key, auth, in_out, ctr, tag_iv)
312
+ aeshwclmulmovbe:: open ( aes_key, gcm_key, ctr, tag_iv, aad, in_out_slice, src)
421
313
}
422
314
423
315
#[ cfg( all( target_arch = "aarch64" , target_endian = "little" ) ) ]
424
316
DynKey :: AesHwClMul ( Combo { aes_key, gcm_key } ) => {
425
317
use crate :: bits:: BitLength ;
426
318
319
+ let in_out =
320
+ Overlapping :: new ( in_out_slice, src. clone ( ) ) . map_err ( error:: erase :: < IndexError > ) ?;
427
321
let mut auth = gcm:: Context :: new ( gcm_key, aad, in_out. len ( ) ) ?;
428
322
let remainder_len = in_out. len ( ) % BLOCK_LEN ;
429
323
let whole_len = in_out. len ( ) - remainder_len;
0 commit comments