5
5
using System . Diagnostics ;
6
6
using System . Runtime . CompilerServices ;
7
7
using System . Runtime . InteropServices ;
8
+ using System . Runtime . InteropServices . Swift ;
8
9
using System . Security . Cryptography ;
9
10
using System . Security . Cryptography . Apple ;
11
+ using Swift . Runtime ;
10
12
11
13
#pragma warning disable CS3016 // Arrays as attribute arguments are not CLS Compliant
12
14
13
15
internal static partial class Interop
14
16
{
15
17
internal static partial class AppleCrypto
16
18
{
19
+ private static byte NullSentinel ;
20
+
21
+ // CryptoKit doesn't do well with a null pointer for the buffer data,
22
+ // so provide a sentinel pointer instead.
23
+ private static ref readonly byte GetSwiftRef ( ReadOnlySpan < byte > b )
24
+ {
25
+ return ref ( b . Length == 0
26
+ ? ref NullSentinel
27
+ : ref MemoryMarshal . GetReference ( b ) ) ;
28
+ }
29
+
17
30
internal static unsafe void ChaCha20Poly1305Encrypt (
18
31
ReadOnlySpan < byte > key ,
19
32
ReadOnlySpan < byte > nonce ,
@@ -24,23 +37,22 @@ internal static unsafe void ChaCha20Poly1305Encrypt(
24
37
{
25
38
fixed ( byte * keyPtr = key )
26
39
fixed ( byte * noncePtr = nonce )
27
- fixed ( byte * plaintextPtr = plaintext )
28
- fixed ( byte * ciphertextPtr = ciphertext )
40
+ fixed ( byte * plaintextPtr = & GetSwiftRef ( plaintext ) )
41
+ fixed ( byte * ciphertextPtr = & GetSwiftRef ( ciphertext ) )
29
42
fixed ( byte * tagPtr = tag )
30
- fixed ( byte * aadPtr = aad )
43
+ fixed ( byte * aadPtr = & GetSwiftRef ( aad ) )
31
44
{
32
- const int Success = 1 ;
33
- int result = AppleCryptoNative_ChaCha20Poly1305Encrypt (
34
- keyPtr , key . Length ,
35
- noncePtr , nonce . Length ,
36
- plaintextPtr , plaintext . Length ,
37
- ciphertextPtr , ciphertext . Length ,
38
- tagPtr , tag . Length ,
39
- aadPtr , aad . Length ) ;
40
-
41
- if ( result != Success )
45
+ AppleCryptoNative_ChaCha20Poly1305Encrypt (
46
+ out SwiftError error ,
47
+ new UnsafeBufferPointer < byte > ( keyPtr , key . Length ) ,
48
+ new UnsafeBufferPointer < byte > ( noncePtr , nonce . Length ) ,
49
+ new UnsafeBufferPointer < byte > ( plaintextPtr , plaintext . Length ) ,
50
+ new UnsafeMutableBufferPointer < byte > ( ciphertextPtr , ciphertext . Length ) ,
51
+ new UnsafeMutableBufferPointer < byte > ( tagPtr , tag . Length ) ,
52
+ new UnsafeBufferPointer < byte > ( aadPtr , aad . Length ) ) ;
53
+
54
+ if ( error . Value != null )
42
55
{
43
- Debug . Assert ( result == 0 ) ;
44
56
CryptographicOperations . ZeroMemory ( ciphertext ) ;
45
57
CryptographicOperations . ZeroMemory ( tag ) ;
46
58
throw new CryptographicException ( ) ;
@@ -58,32 +70,30 @@ internal static unsafe void ChaCha20Poly1305Decrypt(
58
70
{
59
71
fixed ( byte * keyPtr = key )
60
72
fixed ( byte * noncePtr = nonce )
61
- fixed ( byte * ciphertextPtr = ciphertext )
73
+ fixed ( byte * ciphertextPtr = & GetSwiftRef ( ciphertext ) )
62
74
fixed ( byte * tagPtr = tag )
63
- fixed ( byte * plaintextPtr = plaintext )
64
- fixed ( byte * aadPtr = aad )
75
+ fixed ( byte * plaintextPtr = & GetSwiftRef ( plaintext ) )
76
+ fixed ( byte * aadPtr = & GetSwiftRef ( aad ) )
65
77
{
66
- const int Success = 1 ;
67
- const int AuthTagMismatch = - 1 ;
68
- int result = AppleCryptoNative_ChaCha20Poly1305Decrypt (
69
- keyPtr , key . Length ,
70
- noncePtr , nonce . Length ,
71
- ciphertextPtr , ciphertext . Length ,
72
- tagPtr , tag . Length ,
73
- plaintextPtr , plaintext . Length ,
74
- aadPtr , aad . Length ) ;
75
-
76
- if ( result != Success )
78
+ AppleCryptoNative_ChaCha20Poly1305Decrypt (
79
+ out SwiftError error ,
80
+ new UnsafeBufferPointer < byte > ( keyPtr , key . Length ) ,
81
+ new UnsafeBufferPointer < byte > ( noncePtr , nonce . Length ) ,
82
+ new UnsafeBufferPointer < byte > ( ciphertextPtr , ciphertext . Length ) ,
83
+ new UnsafeBufferPointer < byte > ( tagPtr , tag . Length ) ,
84
+ new UnsafeMutableBufferPointer < byte > ( plaintextPtr , plaintext . Length ) ,
85
+ new UnsafeBufferPointer < byte > ( aadPtr , aad . Length ) ) ;
86
+
87
+ if ( error . Value != null )
77
88
{
78
89
CryptographicOperations . ZeroMemory ( plaintext ) ;
79
90
80
- if ( result == AuthTagMismatch )
91
+ if ( AppleCryptoNative_IsAuthenticationFailure ( error . Value ) )
81
92
{
82
93
throw new AuthenticationTagMismatchException ( ) ;
83
94
}
84
95
else
85
96
{
86
- Debug . Assert ( result == 0 ) ;
87
97
throw new CryptographicException ( ) ;
88
98
}
89
99
}
@@ -100,23 +110,22 @@ internal static unsafe void AesGcmEncrypt(
100
110
{
101
111
fixed ( byte * keyPtr = key )
102
112
fixed ( byte * noncePtr = nonce )
103
- fixed ( byte * plaintextPtr = plaintext )
104
- fixed ( byte * ciphertextPtr = ciphertext )
113
+ fixed ( byte * plaintextPtr = & GetSwiftRef ( plaintext ) )
114
+ fixed ( byte * ciphertextPtr = & GetSwiftRef ( ciphertext ) )
105
115
fixed ( byte * tagPtr = tag )
106
- fixed ( byte * aadPtr = aad )
116
+ fixed ( byte * aadPtr = & GetSwiftRef ( aad ) )
107
117
{
108
- const int Success = 1 ;
109
- int result = AppleCryptoNative_AesGcmEncrypt (
110
- keyPtr , key . Length ,
111
- noncePtr , nonce . Length ,
112
- plaintextPtr , plaintext . Length ,
113
- ciphertextPtr , ciphertext . Length ,
114
- tagPtr , tag . Length ,
115
- aadPtr , aad . Length ) ;
116
-
117
- if ( result != Success )
118
+ AppleCryptoNative_AesGcmEncrypt (
119
+ out SwiftError error ,
120
+ new UnsafeBufferPointer < byte > ( keyPtr , key . Length ) ,
121
+ new UnsafeBufferPointer < byte > ( noncePtr , nonce . Length ) ,
122
+ new UnsafeBufferPointer < byte > ( plaintextPtr , plaintext . Length ) ,
123
+ new UnsafeMutableBufferPointer < byte > ( ciphertextPtr , ciphertext . Length ) ,
124
+ new UnsafeMutableBufferPointer < byte > ( tagPtr , tag . Length ) ,
125
+ new UnsafeBufferPointer < byte > ( aadPtr , aad . Length ) ) ;
126
+
127
+ if ( error . Value != null )
118
128
{
119
- Debug . Assert ( result == 0 ) ;
120
129
CryptographicOperations . ZeroMemory ( ciphertext ) ;
121
130
CryptographicOperations . ZeroMemory ( tag ) ;
122
131
throw new CryptographicException ( ) ;
@@ -134,32 +143,30 @@ internal static unsafe void AesGcmDecrypt(
134
143
{
135
144
fixed ( byte * keyPtr = key )
136
145
fixed ( byte * noncePtr = nonce )
137
- fixed ( byte * ciphertextPtr = ciphertext )
146
+ fixed ( byte * ciphertextPtr = & GetSwiftRef ( ciphertext ) )
138
147
fixed ( byte * tagPtr = tag )
139
- fixed ( byte * plaintextPtr = plaintext )
140
- fixed ( byte * aadPtr = aad )
148
+ fixed ( byte * plaintextPtr = & GetSwiftRef ( plaintext ) )
149
+ fixed ( byte * aadPtr = & GetSwiftRef ( aad ) )
141
150
{
142
- const int Success = 1 ;
143
- const int AuthTagMismatch = - 1 ;
144
- int result = AppleCryptoNative_AesGcmDecrypt (
145
- keyPtr , key . Length ,
146
- noncePtr , nonce . Length ,
147
- ciphertextPtr , ciphertext . Length ,
148
- tagPtr , tag . Length ,
149
- plaintextPtr , plaintext . Length ,
150
- aadPtr , aad . Length ) ;
151
-
152
- if ( result != Success )
151
+ AppleCryptoNative_AesGcmDecrypt (
152
+ out SwiftError error ,
153
+ new UnsafeBufferPointer < byte > ( keyPtr , key . Length ) ,
154
+ new UnsafeBufferPointer < byte > ( noncePtr , nonce . Length ) ,
155
+ new UnsafeBufferPointer < byte > ( ciphertextPtr , ciphertext . Length ) ,
156
+ new UnsafeBufferPointer < byte > ( tagPtr , tag . Length ) ,
157
+ new UnsafeMutableBufferPointer < byte > ( plaintextPtr , plaintext . Length ) ,
158
+ new UnsafeBufferPointer < byte > ( aadPtr , aad . Length ) ) ;
159
+
160
+ if ( error . Value != null )
153
161
{
154
162
CryptographicOperations . ZeroMemory ( plaintext ) ;
155
163
156
- if ( result == AuthTagMismatch )
164
+ if ( AppleCryptoNative_IsAuthenticationFailure ( error . Value ) )
157
165
{
158
166
throw new AuthenticationTagMismatchException ( ) ;
159
167
}
160
168
else
161
169
{
162
- Debug . Assert ( result == 0 ) ;
163
170
throw new CryptographicException ( ) ;
164
171
}
165
172
}
@@ -168,66 +175,51 @@ internal static unsafe void AesGcmDecrypt(
168
175
169
176
[ LibraryImport ( Libraries . AppleCryptoNative ) ]
170
177
[ UnmanagedCallConv ( CallConvs = [ typeof ( CallConvSwift ) ] ) ]
171
- private static unsafe partial int AppleCryptoNative_ChaCha20Poly1305Encrypt (
172
- byte * keyPtr ,
173
- int keyLength ,
174
- byte * noncePtr ,
175
- int nonceLength ,
176
- byte * plaintextPtr ,
177
- int plaintextLength ,
178
- byte * ciphertextPtr ,
179
- int ciphertextLength ,
180
- byte * tagPtr ,
181
- int tagLength ,
182
- byte * aadPtr ,
183
- int aadLength ) ;
178
+ private static unsafe partial void AppleCryptoNative_ChaCha20Poly1305Encrypt (
179
+ out SwiftError error ,
180
+ UnsafeBufferPointer < byte > key ,
181
+ UnsafeBufferPointer < byte > nonce ,
182
+ UnsafeBufferPointer < byte > plaintext ,
183
+ UnsafeMutableBufferPointer < byte > ciphertext ,
184
+ UnsafeMutableBufferPointer < byte > tag ,
185
+ UnsafeBufferPointer < byte > aad ) ;
184
186
185
187
[ LibraryImport ( Libraries . AppleCryptoNative ) ]
186
188
[ UnmanagedCallConv ( CallConvs = [ typeof ( CallConvSwift ) ] ) ]
187
- private static unsafe partial int AppleCryptoNative_ChaCha20Poly1305Decrypt (
188
- byte * keyPtr ,
189
- int keyLength ,
190
- byte * noncePtr ,
191
- int nonceLength ,
192
- byte * ciphertextPtr ,
193
- int ciphertextLength ,
194
- byte * tagPtr ,
195
- int tagLength ,
196
- byte * plaintextPtr ,
197
- int plaintextLength ,
198
- byte * aadPtr ,
199
- int aadLength ) ;
189
+ private static unsafe partial void AppleCryptoNative_ChaCha20Poly1305Decrypt (
190
+ out SwiftError error ,
191
+ UnsafeBufferPointer < byte > key ,
192
+ UnsafeBufferPointer < byte > nonce ,
193
+ UnsafeBufferPointer < byte > ciphertext ,
194
+ UnsafeBufferPointer < byte > tag ,
195
+ UnsafeMutableBufferPointer < byte > plaintext ,
196
+ UnsafeBufferPointer < byte > aad ) ;
200
197
201
198
[ LibraryImport ( Libraries . AppleCryptoNative ) ]
202
199
[ UnmanagedCallConv ( CallConvs = [ typeof ( CallConvSwift ) ] ) ]
203
- private static unsafe partial int AppleCryptoNative_AesGcmEncrypt (
204
- byte * keyPtr ,
205
- int keyLength ,
206
- byte * noncePtr ,
207
- int nonceLength ,
208
- byte * plaintextPtr ,
209
- int plaintextLength ,
210
- byte * ciphertextPtr ,
211
- int ciphertextLength ,
212
- byte * tagPtr ,
213
- int tagLength ,
214
- byte * aadPtr ,
215
- int aadLength ) ;
200
+ private static unsafe partial void AppleCryptoNative_AesGcmEncrypt (
201
+ out SwiftError error ,
202
+ UnsafeBufferPointer < byte > key ,
203
+ UnsafeBufferPointer < byte > nonce ,
204
+ UnsafeBufferPointer < byte > plaintext ,
205
+ UnsafeMutableBufferPointer < byte > ciphertext ,
206
+ UnsafeMutableBufferPointer < byte > tag ,
207
+ UnsafeBufferPointer < byte > aad ) ;
216
208
217
209
[ LibraryImport ( Libraries . AppleCryptoNative ) ]
218
210
[ UnmanagedCallConv ( CallConvs = [ typeof ( CallConvSwift ) ] ) ]
219
- private static unsafe partial int AppleCryptoNative_AesGcmDecrypt (
220
- byte * keyPtr ,
221
- int keyLength ,
222
- byte * noncePtr ,
223
- int nonceLength ,
224
- byte * ciphertextPtr ,
225
- int ciphertextLength ,
226
- byte * tagPtr ,
227
- int tagLength ,
228
- byte * plaintextPtr ,
229
- int plaintextLength ,
230
- byte * aadPtr ,
231
- int aadLength ) ;
211
+ private static unsafe partial void AppleCryptoNative_AesGcmDecrypt (
212
+ out SwiftError error ,
213
+ UnsafeBufferPointer < byte > key ,
214
+ UnsafeBufferPointer < byte > nonce ,
215
+ UnsafeBufferPointer < byte > ciphertext ,
216
+ UnsafeBufferPointer < byte > tag ,
217
+ UnsafeMutableBufferPointer < byte > plaintext ,
218
+ UnsafeBufferPointer < byte > aad ) ;
219
+
220
+ [ LibraryImport ( Libraries . AppleCryptoNative ) ]
221
+ [ UnmanagedCallConv ( CallConvs = new [ ] { typeof ( CallConvSwift ) } ) ]
222
+ [ return : MarshalAs ( UnmanagedType . U1 ) ]
223
+ private static unsafe partial bool AppleCryptoNative_IsAuthenticationFailure ( void * error ) ;
232
224
}
233
225
}
0 commit comments