@@ -45,15 +45,15 @@ impl Key {
45
45
impl Key {
46
46
#[ inline]
47
47
pub fn encrypt_in_place ( & self , counter : Counter , in_out : & mut [ u8 ] ) {
48
- self . encrypt_less_safe ( counter, in_out, 0 ..) ;
48
+ self . encrypt_within ( counter, in_out, 0 ..) ;
49
49
}
50
50
51
51
#[ inline]
52
52
pub fn encrypt_iv_xor_in_place ( & self , iv : Iv , in_out : & mut [ u8 ; 32 ] ) {
53
53
// It is safe to use `into_counter_for_single_block_less_safe()`
54
54
// because `in_out` is exactly one block long.
55
55
debug_assert ! ( in_out. len( ) <= BLOCK_LEN ) ;
56
- self . encrypt_less_safe ( iv. into_counter_for_single_block_less_safe ( ) , in_out, 0 .. ) ;
56
+ self . encrypt_in_place ( iv. into_counter_for_single_block_less_safe ( ) , in_out) ;
57
57
}
58
58
59
59
#[ inline]
@@ -62,32 +62,14 @@ impl Key {
62
62
let iv = Iv :: assume_unique_for_key ( sample) ;
63
63
64
64
debug_assert ! ( out. len( ) <= BLOCK_LEN ) ;
65
- self . encrypt_less_safe ( iv. into_counter_for_single_block_less_safe ( ) , & mut out, 0 .. ) ;
65
+ self . encrypt_in_place ( iv. into_counter_for_single_block_less_safe ( ) , & mut out) ;
66
66
67
67
out
68
68
}
69
69
70
70
/// Analogous to `slice::copy_within()`.
71
+ #[ inline( always) ]
71
72
pub fn encrypt_within ( & self , counter : Counter , in_out : & mut [ u8 ] , src : RangeFrom < usize > ) {
72
- // XXX: The x86 and at least one branch of the ARM assembly language
73
- // code doesn't allow overlapping input and output unless they are
74
- // exactly overlapping. TODO: Figure out which branch of the ARM code
75
- // has this limitation and come up with a better solution.
76
- //
77
- // https://rt.openssl.org/Ticket/Display.html?id=4362
78
- if cfg ! ( any( target_arch = "arm" , target_arch = "x86" ) ) && src. start != 0 {
79
- let len = in_out. len ( ) - src. start ;
80
- in_out. copy_within ( src, 0 ) ;
81
- self . encrypt_in_place ( counter, & mut in_out[ ..len] ) ;
82
- } else {
83
- self . encrypt_less_safe ( counter, in_out, src) ;
84
- }
85
- }
86
-
87
- /// This is "less safe" because it skips the important check that `encrypt_within` does.
88
- /// Only call this with `src` equal to `0..` or from `encrypt_within`.
89
- #[ inline]
90
- fn encrypt_less_safe ( & self , counter : Counter , in_out : & mut [ u8 ] , src : RangeFrom < usize > ) {
91
73
#[ cfg( any(
92
74
target_arch = "aarch64" ,
93
75
target_arch = "arm" ,
@@ -103,6 +85,20 @@ impl Key {
103
85
) {
104
86
let in_out_len = in_out. len ( ) . checked_sub ( src. start ) . unwrap ( ) ;
105
87
88
+ // XXX: The x86 and at least one branch of the ARM assembly language
89
+ // code doesn't allow overlapping input and output unless they are
90
+ // exactly overlapping. TODO: Figure out which branch of the ARM code
91
+ // has this limitation and come up with a better solution.
92
+ //
93
+ // https://rt.openssl.org/Ticket/Display.html?id=4362
94
+ let ( output, input) =
95
+ if cfg ! ( any( target_arch = "aarch64" , target_arch = "x86_64" ) ) || src. start == 0 {
96
+ ( in_out. as_mut_ptr ( ) , in_out[ src] . as_ptr ( ) )
97
+ } else {
98
+ in_out. copy_within ( src, 0 ) ;
99
+ ( in_out. as_mut_ptr ( ) , in_out. as_ptr ( ) )
100
+ } ;
101
+
106
102
// There's no need to worry if `counter` is incremented because it is
107
103
// owned here and we drop immediately after the call.
108
104
prefixed_extern ! {
@@ -114,15 +110,7 @@ impl Key {
114
110
counter: & Counter ,
115
111
) ;
116
112
}
117
- unsafe {
118
- ChaCha20_ctr32 (
119
- in_out. as_mut_ptr ( ) ,
120
- in_out[ src] . as_ptr ( ) ,
121
- in_out_len,
122
- key. words_less_safe ( ) ,
123
- & counter,
124
- )
125
- }
113
+ unsafe { ChaCha20_ctr32 ( output, input, in_out_len, key. words_less_safe ( ) , & counter) }
126
114
}
127
115
128
116
#[ cfg( not( any(
0 commit comments