2 * Copyright 2009 Henri Verbeet for CodeWeavers
3 * Copyright 2018 Hans Leidekker for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "wine/port.h"
29 #ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
30 #include <AvailabilityMacros.h>
31 #include <CommonCrypto/CommonCryptor.h>
35 #define WIN32_NO_STATUS
41 #include "bcrypt_internal.h"
43 #include "wine/debug.h"
44 #include "wine/unicode.h"
46 #if defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 && !defined(HAVE_GNUTLS_CIPHER_INIT)
47 WINE_DEFAULT_DEBUG_CHANNEL(bcrypt
);
51 CCCryptorRef ref_encrypt
;
52 CCCryptorRef ref_decrypt
;
54 C_ASSERT( sizeof(struct key_data
) <= sizeof(((struct key
*)0)->private) );
56 static struct key_data
*key_data( struct key
*key
)
58 return (struct key_data
*)key
->private;
61 static NTSTATUS CDECL
key_set_property( struct key
*key
, const WCHAR
*prop
, UCHAR
*value
, ULONG size
, ULONG flags
)
63 if (!strcmpW( prop
, BCRYPT_CHAINING_MODE
))
65 if (!strcmpW( (WCHAR
*)value
, BCRYPT_CHAIN_MODE_ECB
))
67 key
->u
.s
.mode
= MODE_ID_ECB
;
68 return STATUS_SUCCESS
;
70 else if (!strcmpW( (WCHAR
*)value
, BCRYPT_CHAIN_MODE_CBC
))
72 key
->u
.s
.mode
= MODE_ID_CBC
;
73 return STATUS_SUCCESS
;
77 FIXME( "unsupported mode %s\n", debugstr_w((WCHAR
*)value
) );
78 return STATUS_NOT_IMPLEMENTED
;
82 FIXME( "unsupported key property %s\n", debugstr_w(prop
) );
83 return STATUS_NOT_IMPLEMENTED
;
86 static NTSTATUS CDECL
key_symmetric_init( struct key
*key
)
91 switch (key
->u
.s
.mode
)
97 FIXME( "mode %u not supported\n", key
->u
.s
.mode
);
98 return STATUS_NOT_SUPPORTED
;
100 return STATUS_SUCCESS
;
103 FIXME( "algorithm %u not supported\n", key
->alg_id
);
104 return STATUS_NOT_SUPPORTED
;
108 static CCMode
get_cryptor_mode( struct key
*key
)
110 switch (key
->u
.s
.mode
)
112 case MODE_ID_ECB
: return kCCModeECB
;
113 case MODE_ID_CBC
: return kCCModeCBC
;
115 FIXME( "unsupported mode %u\n", key
->u
.s
.mode
);
120 static void CDECL
key_symmetric_vector_reset( struct key
*key
)
122 if (!key_data(key
)->ref_encrypt
) return;
124 TRACE( "invalidating cryptor handles\n" );
125 CCCryptorRelease( key_data(key
)->ref_encrypt
);
126 key_data(key
)->ref_encrypt
= NULL
;
128 CCCryptorRelease( key_data(key
)->ref_decrypt
);
129 key_data(key
)->ref_decrypt
= NULL
;
132 static NTSTATUS
init_cryptor_handles( struct key
*key
)
134 CCCryptorStatus status
;
137 if (key_data(key
)->ref_encrypt
) return STATUS_SUCCESS
;
138 if (!(mode
= get_cryptor_mode( key
))) return STATUS_NOT_SUPPORTED
;
140 if ((status
= CCCryptorCreateWithMode( kCCEncrypt
, mode
, kCCAlgorithmAES128
, ccNoPadding
, key
->u
.s
.vector
,
141 key
->u
.s
.secret
, key
->u
.s
.secret_len
, NULL
, 0, 0, 0,
142 &key_data(key
)->ref_encrypt
)) != kCCSuccess
)
144 WARN( "CCCryptorCreateWithMode failed %d\n", status
);
145 return STATUS_INTERNAL_ERROR
;
147 if ((status
= CCCryptorCreateWithMode( kCCDecrypt
, mode
, kCCAlgorithmAES128
, ccNoPadding
, key
->u
.s
.vector
,
148 key
->u
.s
.secret
, key
->u
.s
.secret_len
, NULL
, 0, 0, 0,
149 &key_data(key
)->ref_decrypt
)) != kCCSuccess
)
151 WARN( "CCCryptorCreateWithMode failed %d\n", status
);
152 CCCryptorRelease( key_data(key
)->ref_encrypt
);
153 key_data(key
)->ref_encrypt
= NULL
;
154 return STATUS_INTERNAL_ERROR
;
157 return STATUS_SUCCESS
;
160 static NTSTATUS CDECL
key_symmetric_set_auth_data( struct key
*key
, UCHAR
*auth_data
, ULONG len
)
162 FIXME( "not implemented on Mac\n" );
163 return STATUS_NOT_IMPLEMENTED
;
166 static NTSTATUS CDECL
key_symmetric_encrypt( struct key
*key
, const UCHAR
*input
, ULONG input_len
, UCHAR
*output
, ULONG output_len
)
168 CCCryptorStatus status
;
171 if ((ret
= init_cryptor_handles( key
))) return ret
;
173 if ((status
= CCCryptorUpdate( key_data(key
)->ref_encrypt
, input
, input_len
, output
, output_len
, NULL
)) != kCCSuccess
)
175 WARN( "CCCryptorUpdate failed %d\n", status
);
176 return STATUS_INTERNAL_ERROR
;
178 return STATUS_SUCCESS
;
181 static NTSTATUS CDECL
key_symmetric_decrypt( struct key
*key
, const UCHAR
*input
, ULONG input_len
, UCHAR
*output
, ULONG output_len
)
183 CCCryptorStatus status
;
186 if ((ret
= init_cryptor_handles( key
))) return ret
;
188 if ((status
= CCCryptorUpdate( key_data(key
)->ref_decrypt
, input
, input_len
, output
, output_len
, NULL
)) != kCCSuccess
)
190 WARN( "CCCryptorUpdate failed %d\n", status
);
191 return STATUS_INTERNAL_ERROR
;
193 return STATUS_SUCCESS
;
196 static NTSTATUS CDECL
key_symmetric_get_tag( struct key
*key
, UCHAR
*tag
, ULONG len
)
198 FIXME( "not implemented on Mac\n" );
199 return STATUS_NOT_IMPLEMENTED
;
202 static void CDECL
key_symmetric_destroy( struct key
*key
)
204 if (key_data(key
)->ref_encrypt
) CCCryptorRelease( key_data(key
)->ref_encrypt
);
205 if (key_data(key
)->ref_decrypt
) CCCryptorRelease( key_data(key
)->ref_decrypt
);
208 static NTSTATUS CDECL
key_asymmetric_init( struct key
*key
)
210 FIXME( "not implemented on Mac\n" );
211 return STATUS_NOT_IMPLEMENTED
;
214 static NTSTATUS CDECL
key_asymmetric_sign( struct key
*key
, void *padding
, UCHAR
*input
, ULONG input_len
, UCHAR
*output
,
215 ULONG output_len
, ULONG
*ret_len
, ULONG flags
)
217 FIXME( "not implemented on Mac\n" );
218 return STATUS_NOT_IMPLEMENTED
;
221 static NTSTATUS CDECL
key_asymmetric_verify( struct key
*key
, void *padding
, UCHAR
*hash
, ULONG hash_len
,
222 UCHAR
*signature
, ULONG signature_len
, DWORD flags
)
224 FIXME( "not implemented on Mac\n" );
225 return STATUS_NOT_IMPLEMENTED
;
228 static NTSTATUS CDECL
key_export_dsa_capi( struct key
*key
, UCHAR
*buf
, ULONG len
, ULONG
*ret_len
)
230 FIXME( "not implemented on Mac\n" );
231 return STATUS_NOT_IMPLEMENTED
;
234 static NTSTATUS CDECL
key_export_ecc( struct key
*key
, UCHAR
*output
, ULONG len
, ULONG
*ret_len
)
236 FIXME( "not implemented on Mac\n" );
237 return STATUS_NOT_IMPLEMENTED
;
240 static NTSTATUS CDECL
key_import_dsa_capi( struct key
*key
, UCHAR
*buf
, ULONG len
)
242 FIXME( "not implemented on Mac\n" );
243 return STATUS_NOT_IMPLEMENTED
;
246 static NTSTATUS CDECL
key_import_ecc( struct key
*key
, UCHAR
*input
, ULONG len
)
248 FIXME( "not implemented on Mac\n" );
249 return STATUS_NOT_IMPLEMENTED
;
252 static NTSTATUS CDECL
key_import_rsa( struct key
*key
, UCHAR
*input
, ULONG len
)
254 FIXME( "not implemented on Mac\n" );
255 return STATUS_NOT_IMPLEMENTED
;
258 static NTSTATUS CDECL
key_asymmetric_generate( struct key
*key
)
260 FIXME( "not implemented on Mac\n" );
261 return STATUS_NOT_IMPLEMENTED
;
264 static void CDECL
key_asymmetric_destroy( struct key
*key
)
268 static NTSTATUS CDECL
key_asymmetric_duplicate( struct key
*key_orig
, struct key
*key_copy
)
270 FIXME( "not implemented on Mac\n" );
271 return STATUS_NOT_IMPLEMENTED
;
274 static NTSTATUS CDECL
key_asymmetric_decrypt( struct key
*key
, UCHAR
*input
, ULONG input_len
,
275 UCHAR
*output
, ULONG output_len
, ULONG
*ret_len
)
277 FIXME( "not implemented on Mac\n" );
278 return STATUS_NOT_IMPLEMENTED
;
281 static const struct key_funcs key_funcs
=
285 key_symmetric_vector_reset
,
286 key_symmetric_set_auth_data
,
287 key_symmetric_encrypt
,
288 key_symmetric_decrypt
,
289 key_symmetric_get_tag
,
290 key_symmetric_destroy
,
292 key_asymmetric_generate
,
293 key_asymmetric_decrypt
,
294 key_asymmetric_duplicate
,
296 key_asymmetric_verify
,
297 key_asymmetric_destroy
,
305 NTSTATUS CDECL
__wine_init_unix_lib( HMODULE module
, DWORD reason
, const void *ptr_in
, void *ptr_out
)
307 if (reason
!= DLL_PROCESS_ATTACH
) return STATUS_SUCCESS
;
308 *(const struct key_funcs
**)ptr_out
= &key_funcs
;
309 return STATUS_SUCCESS
;