bcrypt: Add initial support for asymmetric keys in BCryptDecrypt().
[wine.git] / dlls / bcrypt / macos.c
blob44906519cef06c064e974927f5a5bdea65ec0808
1 /*
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
21 #if 0
22 #pragma makedep unix
23 #endif
25 #include "config.h"
26 #include "wine/port.h"
28 #include <stdarg.h>
29 #ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
30 #include <AvailabilityMacros.h>
31 #include <CommonCrypto/CommonCryptor.h>
32 #endif
34 #include "ntstatus.h"
35 #define WIN32_NO_STATUS
36 #include "windef.h"
37 #include "winbase.h"
38 #include "ntsecapi.h"
39 #include "bcrypt.h"
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);
49 struct key_data
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;
75 else
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 )
88 switch (key->alg_id)
90 case ALG_ID_AES:
91 switch (key->u.s.mode)
93 case MODE_ID_ECB:
94 case MODE_ID_CBC:
95 break;
96 default:
97 FIXME( "mode %u not supported\n", key->u.s.mode );
98 return STATUS_NOT_SUPPORTED;
100 return STATUS_SUCCESS;
102 default:
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;
114 default:
115 FIXME( "unsupported mode %u\n", key->u.s.mode );
116 return 0;
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;
135 CCMode mode;
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;
169 NTSTATUS ret;
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;
184 NTSTATUS ret;
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 )
277 FIXME( "not implemented on Mac\n" );
278 return STATUS_NOT_IMPLEMENTED;
281 static const struct key_funcs key_funcs =
283 key_set_property,
284 key_symmetric_init,
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,
291 key_asymmetric_init,
292 key_asymmetric_generate,
293 key_asymmetric_decrypt,
294 key_asymmetric_duplicate,
295 key_asymmetric_sign,
296 key_asymmetric_verify,
297 key_asymmetric_destroy,
298 key_export_dsa_capi,
299 key_export_ecc,
300 key_import_dsa_capi,
301 key_import_ecc,
302 key_import_rsa
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;
312 #endif