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
22 #include "wine/port.h"
25 #ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
26 #include <AvailabilityMacros.h>
27 #include <CommonCrypto/CommonCryptor.h>
31 #define WIN32_NO_STATUS
37 #include "bcrypt_internal.h"
39 #include "wine/debug.h"
40 #include "wine/heap.h"
41 #include "wine/library.h"
42 #include "wine/unicode.h"
44 #if defined(HAVE_COMMONCRYPTO_COMMONCRYPTOR_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 && !defined(HAVE_GNUTLS_CIPHER_INIT)
45 WINE_DEFAULT_DEBUG_CHANNEL(bcrypt
);
47 NTSTATUS
key_set_property( struct key
*key
, const WCHAR
*prop
, UCHAR
*value
, ULONG size
, ULONG flags
)
49 if (!strcmpW( prop
, BCRYPT_CHAINING_MODE
))
51 if (!strncmpW( (WCHAR
*)value
, BCRYPT_CHAIN_MODE_ECB
, size
))
53 key
->u
.s
.mode
= MODE_ID_ECB
;
54 return STATUS_SUCCESS
;
56 else if (!strncmpW( (WCHAR
*)value
, BCRYPT_CHAIN_MODE_CBC
, size
))
58 key
->u
.s
.mode
= MODE_ID_CBC
;
59 return STATUS_SUCCESS
;
63 FIXME( "unsupported mode %s\n", debugstr_wn( (WCHAR
*)value
, size
) );
64 return STATUS_NOT_IMPLEMENTED
;
68 FIXME( "unsupported key property %s\n", debugstr_w(prop
) );
69 return STATUS_NOT_IMPLEMENTED
;
72 static ULONG
get_block_size( struct algorithm
*alg
)
74 ULONG ret
= 0, size
= sizeof(ret
);
75 get_alg_property( alg
, BCRYPT_BLOCK_LENGTH
, (UCHAR
*)&ret
, sizeof(ret
), &size
);
79 NTSTATUS
key_symmetric_init( struct key
*key
, struct algorithm
*alg
, const UCHAR
*secret
, ULONG secret_len
)
90 FIXME( "mode %u not supported\n", alg
->mode
);
91 return STATUS_NOT_SUPPORTED
;
96 FIXME( "algorithm %u not supported\n", alg
->id
);
97 return STATUS_NOT_SUPPORTED
;
100 if (!(key
->u
.s
.block_size
= get_block_size( alg
))) return STATUS_INVALID_PARAMETER
;
101 if (!(key
->u
.s
.secret
= heap_alloc( secret_len
))) return STATUS_NO_MEMORY
;
102 memcpy( key
->u
.s
.secret
, secret
, secret_len
);
103 key
->u
.s
.secret_len
= secret_len
;
105 key
->alg_id
= alg
->id
;
106 key
->u
.s
.mode
= alg
->mode
;
107 key
->u
.s
.ref_encrypt
= NULL
; /* initialized on first use */
108 key
->u
.s
.ref_decrypt
= NULL
;
110 return STATUS_SUCCESS
;
113 static CCMode
get_cryptor_mode( struct key
*key
)
115 switch (key
->u
.s
.mode
)
117 case MODE_ID_ECB
: return kCCModeECB
;
118 case MODE_ID_CBC
: return kCCModeCBC
;
120 FIXME( "unsupported mode %u\n", key
->u
.s
.mode
);
125 NTSTATUS
key_symmetric_set_params( struct key
*key
, UCHAR
*iv
, ULONG iv_len
)
127 CCCryptorStatus status
;
130 if (!(mode
= get_cryptor_mode( key
))) return STATUS_NOT_SUPPORTED
;
132 if (key
->u
.s
.ref_encrypt
)
134 CCCryptorRelease( key
->u
.s
.ref_encrypt
);
135 key
->u
.s
.ref_encrypt
= NULL
;
137 if (key
->u
.s
.ref_decrypt
)
139 CCCryptorRelease( key
->u
.s
.ref_decrypt
);
140 key
->u
.s
.ref_decrypt
= NULL
;
143 if ((status
= CCCryptorCreateWithMode( kCCEncrypt
, mode
, kCCAlgorithmAES128
, ccNoPadding
, iv
, key
->u
.s
.secret
,
144 key
->u
.s
.secret_len
, NULL
, 0, 0, 0, &key
->u
.s
.ref_encrypt
)) != kCCSuccess
)
146 WARN( "CCCryptorCreateWithMode failed %d\n", status
);
147 return STATUS_INTERNAL_ERROR
;
149 if ((status
= CCCryptorCreateWithMode( kCCDecrypt
, mode
, kCCAlgorithmAES128
, ccNoPadding
, iv
, key
->u
.s
.secret
,
150 key
->u
.s
.secret_len
, NULL
, 0, 0, 0, &key
->u
.s
.ref_decrypt
)) != kCCSuccess
)
152 WARN( "CCCryptorCreateWithMode failed %d\n", status
);
153 CCCryptorRelease( key
->u
.s
.ref_encrypt
);
154 key
->u
.s
.ref_encrypt
= NULL
;
155 return STATUS_INTERNAL_ERROR
;
158 return STATUS_SUCCESS
;
161 NTSTATUS
key_symmetric_set_auth_data( struct key
*key
, UCHAR
*auth_data
, ULONG len
)
163 FIXME( "not implemented on Mac\n" );
164 return STATUS_NOT_IMPLEMENTED
;
167 NTSTATUS
key_symmetric_encrypt( struct key
*key
, const UCHAR
*input
, ULONG input_len
, UCHAR
*output
, ULONG output_len
)
169 CCCryptorStatus status
;
170 if ((status
= CCCryptorUpdate( key
->u
.s
.ref_encrypt
, input
, input_len
, output
, output_len
, NULL
)) != kCCSuccess
)
172 WARN( "CCCryptorUpdate failed %d\n", status
);
173 return STATUS_INTERNAL_ERROR
;
175 return STATUS_SUCCESS
;
178 NTSTATUS
key_symmetric_decrypt( struct key
*key
, const UCHAR
*input
, ULONG input_len
, UCHAR
*output
, ULONG output_len
)
180 CCCryptorStatus status
;
181 if ((status
= CCCryptorUpdate( key
->u
.s
.ref_decrypt
, input
, input_len
, output
, output_len
, NULL
)) != kCCSuccess
)
183 WARN( "CCCryptorUpdate failed %d\n", status
);
184 return STATUS_INTERNAL_ERROR
;
186 return STATUS_SUCCESS
;
189 NTSTATUS
key_symmetric_get_tag( struct key
*key
, UCHAR
*tag
, ULONG len
)
191 FIXME( "not implemented on Mac\n" );
192 return STATUS_NOT_IMPLEMENTED
;
195 NTSTATUS
key_asymmetric_init( struct key
*key
, struct algorithm
*alg
, const UCHAR
*pubkey
, ULONG pubkey_len
)
197 FIXME( "not implemented on Mac\n" );
198 return STATUS_NOT_IMPLEMENTED
;
201 NTSTATUS
key_asymmetric_verify( struct key
*key
, void *padding
, UCHAR
*hash
, ULONG hash_len
, UCHAR
*signature
,
202 ULONG signature_len
, DWORD flags
)
204 FIXME( "not implemented on Mac\n" );
205 return STATUS_NOT_IMPLEMENTED
;
208 NTSTATUS
key_destroy( struct key
*key
)
210 if (key
->u
.s
.ref_encrypt
) CCCryptorRelease( key
->u
.s
.ref_encrypt
);
211 if (key
->u
.s
.ref_decrypt
) CCCryptorRelease( key
->u
.s
.ref_decrypt
);
212 heap_free( key
->u
.s
.secret
);
214 return STATUS_SUCCESS
;