]> git.saurik.com Git - apple/security.git/blob - tests/secdmockaks/mockaks.m
Security-59306.61.1.tar.gz
[apple/security.git] / tests / secdmockaks / mockaks.m
1 /*
2 * Copyright (c) 2018 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #import <TargetConditionals.h>
25 #if !TARGET_OS_BRIDGE
26
27 #import "SecKeybagSupport.h"
28
29 #if __has_include(<libaks.h>)
30 #import <libaks.h>
31 #endif
32
33 #if __has_include(<libaks_ref_key.h>)
34 #import <libaks_ref_key.h>
35 #endif
36
37 #if __has_include(<MobileKeyBag/MobileKeyBag.h>)
38 #import <MobileKeyBag/MobileKeyBag.h>
39 #endif
40
41 #include <os/variant_private.h>
42
43 #import <ctkclient/ctkclient.h>
44 #import <coreauthd_spi.h>
45 #import <ACMLib.h>
46 #import <LocalAuthentication/LAPublicDefines.h>
47 #import <LocalAuthentication/LAPrivateDefines.h>
48 #import <LocalAuthentication/LACFSupport.h>
49 #import <SecurityFoundation/SFEncryptionOperation.h>
50 #import "mockaks.h"
51 #import "utilities/der_plist.h"
52 #import "tests/secdmockaks/generated_source/MockAKSRefKey.h"
53 #import "tests/secdmockaks/generated_source/MockAKSOptionalParameters.h"
54
55 bool hwaes_key_available(void)
56 {
57 return false;
58 }
59
60 #define SET_FLAG_ON(v, flag) v |= (flag)
61 #define SET_FLAG_OFF(v, flag) v &= ~(flag)
62
63 @interface SecMockAKS ()
64 @property (class, readonly) NSMutableDictionary<NSNumber*, NSNumber*>* lockedStates;
65 @property (class, readonly) dispatch_queue_t mutabilityQueue;
66 @end
67
68 @implementation SecMockAKS
69 static NSMutableDictionary* _lockedStates = nil;
70 static dispatch_queue_t _mutabilityQueue = nil;
71 static keybag_state_t _keybag_state = keybag_state_unlocked | keybag_state_been_unlocked;
72 static NSMutableArray<NSError *>* _decryptRefKeyErrors = nil;
73 /*
74 * Method that limit where this rather in-secure version of AKS can run
75 */
76
77 + (void)trapdoor {
78 static dispatch_once_t onceToken;
79 dispatch_once(&onceToken, ^{
80 #if DEBUG || TARGET_OS_SIMULATOR
81 return;
82 #else
83 const char *argv0 = getprogname();
84
85 if (strcmp(argv0, "securityd") == 0 || strcmp(argv0, "secd") == 0) {
86 abort();
87 }
88 if (os_variant_has_internal_content("securityd")) {
89 return;
90 }
91 #if TARGET_OS_IPHONE /* all three platforms: ios, watch, tvos */
92 if (os_variant_uses_ephemeral_storage("securityd")) {
93 return;
94 }
95 if (os_variant_allows_internal_security_policies("securityd")) {
96 return;
97 }
98 abort();
99 #endif /* TARGET_OS_IPHONE */
100 #endif /* !DEBUG || !TARGET_OS_SIMULATOR */
101 });
102 }
103
104 + (NSMutableDictionary*)lockedStates
105 {
106 if(_lockedStates == nil) {
107 _lockedStates = [NSMutableDictionary dictionary];
108 }
109 return _lockedStates;
110 }
111
112 + (dispatch_queue_t)mutabilityQueue
113 {
114 static dispatch_once_t onceToken;
115 dispatch_once(&onceToken, ^{
116 _mutabilityQueue = dispatch_queue_create("SecMockAKS", DISPATCH_QUEUE_SERIAL);
117 });
118 return _mutabilityQueue;
119 }
120
121 + (keybag_state_t)keybag_state
122 {
123 return _keybag_state;
124 }
125
126 + (void)setKeybag_state:(keybag_state_t)keybag_state
127 {
128 _keybag_state = keybag_state;
129 }
130
131 + (void)reset
132 {
133 dispatch_sync(self.mutabilityQueue, ^{
134 [self.lockedStates removeAllObjects];
135 self.keybag_state = keybag_state_unlocked;
136 });
137 }
138
139 + (bool)isLocked:(keyclass_t)key_class
140 {
141 __block bool isLocked = false;
142 dispatch_sync(self.mutabilityQueue, ^{
143 NSNumber* key = [NSNumber numberWithInt:key_class];
144 isLocked = [self.lockedStates[key] boolValue];
145 });
146 return isLocked;
147 }
148
149 + (bool)isSEPDown
150 {
151 return false;
152 }
153
154 + (bool)useGenerationCount
155 {
156 return false;
157 }
158
159 + (void)lockClassA
160 {
161 dispatch_sync(self.mutabilityQueue, ^{
162 self.lockedStates[[NSNumber numberWithInt:key_class_a]] = [NSNumber numberWithBool:YES];
163 self.lockedStates[[NSNumber numberWithInt:key_class_ak]] = [NSNumber numberWithBool:YES];
164 self.lockedStates[[NSNumber numberWithInt:key_class_aku]] = [NSNumber numberWithBool:YES];
165 self.lockedStates[[NSNumber numberWithInt:key_class_akpu]] = [NSNumber numberWithBool:YES];
166
167 SET_FLAG_ON(self.keybag_state, keybag_state_locked);
168 SET_FLAG_OFF(self.keybag_state, keybag_state_unlocked);
169 // don't touch keybag_state_been_unlocked; leave it as-is
170 });
171 }
172
173 // Simulate device being in "before first unlock"
174 + (void)lockClassA_C
175 {
176 dispatch_sync(self.mutabilityQueue, ^{
177 self.lockedStates[[NSNumber numberWithInt:key_class_a]] = [NSNumber numberWithBool:YES];
178 self.lockedStates[[NSNumber numberWithInt:key_class_ak]] = [NSNumber numberWithBool:YES];
179 self.lockedStates[[NSNumber numberWithInt:key_class_aku]] = [NSNumber numberWithBool:YES];
180 self.lockedStates[[NSNumber numberWithInt:key_class_akpu]] = [NSNumber numberWithBool:YES];
181 self.lockedStates[[NSNumber numberWithInt:key_class_c]] = [NSNumber numberWithBool:YES];
182 self.lockedStates[[NSNumber numberWithInt:key_class_ck]] = [NSNumber numberWithBool:YES];
183 self.lockedStates[[NSNumber numberWithInt:key_class_cku]] = [NSNumber numberWithBool:YES];
184
185 SET_FLAG_ON(self.keybag_state, keybag_state_locked);
186 SET_FLAG_OFF(self.keybag_state, keybag_state_unlocked);
187 SET_FLAG_OFF(self.keybag_state, keybag_state_been_unlocked);
188 });
189 }
190
191 + (void)unlockAllClasses
192 {
193 dispatch_sync(self.mutabilityQueue, ^{
194 [self.lockedStates removeAllObjects];
195
196 SET_FLAG_OFF(self.keybag_state, keybag_state_locked);
197 SET_FLAG_ON(self.keybag_state, keybag_state_unlocked);
198 SET_FLAG_ON(self.keybag_state, keybag_state_been_unlocked);
199 });
200 }
201
202 + (void)failNextDecryptRefKey: (NSError* _Nonnull) decryptRefKeyError {
203 if (_decryptRefKeyErrors == NULL) {
204 _decryptRefKeyErrors = [NSMutableArray array];
205 }
206 @synchronized(_decryptRefKeyErrors) {
207 [_decryptRefKeyErrors addObject: decryptRefKeyError];
208 }
209 }
210
211 + (NSError * _Nullable)popDecryptRefKeyFailure {
212 NSError* error = nil;
213 if (_decryptRefKeyErrors == NULL) {
214 return nil;
215 }
216 @synchronized(_decryptRefKeyErrors) {
217 if(_decryptRefKeyErrors.count > 0) {
218 error = _decryptRefKeyErrors[0];
219 [_decryptRefKeyErrors removeObjectAtIndex:0];
220 }
221 }
222 return error;
223 }
224
225
226 @end
227
228 kern_return_t
229 aks_load_bag(const void * data, int length, keybag_handle_t* handle)
230 {
231 *handle = 17;
232 return 0;
233 }
234
235 kern_return_t
236 aks_create_bag(const void * passcode, int length, keybag_type_t type, keybag_handle_t* handle)
237 {
238 [SecMockAKS unlockAllClasses];
239 *handle = 17;
240 return 0;
241 }
242
243 kern_return_t
244 aks_unload_bag(keybag_handle_t handle)
245 {
246 return kAKSReturnSuccess;
247 }
248
249 kern_return_t
250 aks_save_bag(keybag_handle_t handle, void ** data, int * length)
251 {
252 assert(handle != bad_keybag_handle);
253 assert(data);
254 assert(length);
255
256 *data = calloc(1, 12);
257 memcpy(*data, "keybag dump", 12);
258 *length = 12;
259
260 return kAKSReturnSuccess;
261 }
262
263 kern_return_t
264 aks_get_system(keybag_handle_t special_handle, keybag_handle_t *handle)
265 {
266 *handle = 17;
267 return kAKSReturnSuccess;
268 }
269
270 kern_return_t
271 aks_get_bag_uuid(keybag_handle_t handle, uuid_t uuid)
272 {
273 memcpy(uuid, "0123456789abcdf", sizeof(uuid_t));
274 return kAKSReturnSuccess;
275 }
276
277 kern_return_t aks_lock_bag(keybag_handle_t handle)
278 {
279 if (handle == KEYBAG_DEVICE) {
280 [SecMockAKS lockClassA];
281 }
282 return kAKSReturnSuccess;
283 }
284
285 kern_return_t aks_unlock_bag(keybag_handle_t handle, const void *passcode, int length)
286 {
287 if (handle == KEYBAG_DEVICE) {
288 [SecMockAKS unlockAllClasses];
289 }
290 return kAKSReturnSuccess;
291 }
292
293 kern_return_t aks_get_lock_state(keybag_handle_t handle, keybag_state_t *state)
294 {
295 *state = SecMockAKS.keybag_state;
296 return kAKSReturnSuccess;
297 }
298
299 //static uint8_t staticAKSKey[32] = "1234567890123456789012";
300
301 #define PADDINGSIZE 8
302
303 kern_return_t
304 aks_wrap_key(const void * key, int key_size, keyclass_t key_class, keybag_handle_t handle, void * wrapped_key, int * wrapped_key_size_inout, keyclass_t * class_out)
305 {
306 [SecMockAKS trapdoor];
307
308 if ([SecMockAKS isSEPDown]) {
309 return kAKSReturnBusy;
310 }
311
312 // Assumes non-device keybags are asym
313 if ([SecMockAKS isLocked:key_class] && handle == KEYBAG_DEVICE) {
314 return kAKSReturnNoPermission;
315 }
316
317 if (class_out) { // Not a required parameter
318 *class_out = key_class;
319 if ([SecMockAKS useGenerationCount]) {
320 *class_out |= (key_class_last + 1);
321 }
322 }
323
324 if (key_size > APPLE_KEYSTORE_MAX_KEY_LEN) {
325 abort();
326 }
327 if (handle != KEYBAG_DEVICE) { // For now assumes non-device bags are asym
328 if (APPLE_KEYSTORE_MAX_ASYM_WRAPPED_KEY_LEN > *wrapped_key_size_inout) {
329 abort();
330 }
331 } else {
332 if (APPLE_KEYSTORE_MAX_SYM_WRAPPED_KEY_LEN > *wrapped_key_size_inout) {
333 abort();
334 }
335 }
336
337 *wrapped_key_size_inout = key_size + PADDINGSIZE;
338 memcpy(wrapped_key, key, key_size);
339 memset(((uint8_t *)wrapped_key) + key_size, 0xff, PADDINGSIZE);
340 return kAKSReturnSuccess;
341 }
342
343 kern_return_t
344 aks_unwrap_key(const void * wrapped_key, int wrapped_key_size, keyclass_t key_class, keybag_handle_t handle, void * key, int * key_size_inout)
345 {
346 [SecMockAKS trapdoor];
347
348 if ([SecMockAKS isSEPDown]) {
349 return kAKSReturnBusy;
350 }
351
352 if ([SecMockAKS isLocked:key_class]) {
353 return kAKSReturnNoPermission;
354 }
355
356 if (wrapped_key_size < PADDINGSIZE) {
357 abort();
358 }
359 static const char expected_padding[PADDINGSIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
360 if (memcmp(((const uint8_t *)wrapped_key) + (wrapped_key_size - PADDINGSIZE), expected_padding, PADDINGSIZE) != 0) {
361 return kAKSReturnDecodeError;
362 }
363 if (*key_size_inout < wrapped_key_size - PADDINGSIZE) {
364 abort();
365 }
366 *key_size_inout = wrapped_key_size - PADDINGSIZE;
367 memcpy(key, wrapped_key, *key_size_inout);
368
369 return kAKSReturnSuccess;
370 }
371
372 @interface MockAKSRefKeyObject: NSObject
373 @property NSData *keyData;
374 @property SFAESKey *key;
375 @property NSData *acmHandle;
376 @property NSData *externalData;
377
378 @property NSData *blob; // blob is exteralized format
379
380 - (instancetype)init NS_UNAVAILABLE;
381 - (instancetype)initWithKeyData:(NSData *)keyData parameters:(NSData *)parameters error:(NSError **)error;
382
383 @end
384 @implementation MockAKSRefKeyObject
385
386 - (instancetype)initWithKeyData:(NSData *)keyData
387 parameters:(NSData *)parameters
388 error:(NSError **)error
389 {
390 if ((self = [super init]) != NULL) {
391
392 self.keyData = [keyData copy];
393 SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize: SFAESKeyBitSize256];
394 @try {
395 self.key = [[SFAESKey alloc] initWithData:self.keyData specifier:keySpecifier error:error];
396 if (self.key == NULL) {
397 return NULL;
398 }
399 } @catch (NSException *exception) {
400 *error = [NSError errorWithDomain:@"foo" code:kAKSReturnBadArgument userInfo:nil];
401 return NULL;
402 }
403
404 MockAKSOptionalParameters *params = [[MockAKSOptionalParameters alloc] initWithData:parameters];
405
406 // enforce that the extra data is DER like
407 if (params.externalData) {
408 CFTypeRef cf = NULL;
409 CFErrorRef cferror = NULL;
410 uint8_t *der = (uint8_t *)params.externalData.bytes;
411 der_decode_plist(NULL, false, &cf, &cferror, der, der + params.externalData.length);
412 if (cf == NULL) {
413 *error = [NSError errorWithDomain:@"foo" code:kAKSReturnBadArgument userInfo:nil];
414 return NULL;
415 }
416 CFReleaseNull(cf);
417 }
418
419
420 self.externalData = params.externalData;
421 self.acmHandle = params.acmHandle;
422
423 MockAKSRefKey *blob = [[MockAKSRefKey alloc] init];
424 blob.key = self.keyData;
425 blob.optionalParams = parameters;
426 self.blob = blob.data;
427 }
428 return self;
429 }
430
431 @end
432
433 int
434 aks_ref_key_create(keybag_handle_t handle, keyclass_t key_class, aks_key_type_t type, const uint8_t *params, size_t params_len, aks_ref_key_t *ot)
435 {
436 MockAKSRefKeyObject *key;
437 @autoreleasepool {
438 [SecMockAKS trapdoor];
439 NSError *error = NULL;
440
441 if ([SecMockAKS isLocked:key_class]) {
442 return kAKSReturnNoPermission;
443 }
444
445 NSData *keyData = [NSData dataWithBytes:"1234567890123456789012345678901" length:32];
446 NSData *parameters = NULL;
447 if (params && params_len != 0) {
448 parameters = [NSData dataWithBytes:params length:params_len];
449 }
450
451 key = [[MockAKSRefKeyObject alloc] initWithKeyData:keyData parameters:parameters error:&error];
452 if(key == NULL) {
453 if (error) {
454 return (int)error.code;
455 }
456 return kAKSReturnError;
457 }
458 }
459
460 *ot = (__bridge_retained aks_ref_key_t)key;
461 return kAKSReturnSuccess;
462 }
463
464 int
465 aks_ref_key_encrypt(aks_ref_key_t handle,
466 const uint8_t *der_params, size_t der_params_len,
467 const void * data, size_t data_len,
468 void ** out_der, size_t * out_der_len)
469 {
470 [SecMockAKS trapdoor];
471
472 // No current error injection
473 NSError* error = nil;
474 NSData* nsdata = [NSData dataWithBytes:data length:data_len];
475
476 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)handle;
477
478 SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:key.key.keySpecifier authenticationMode:SFAuthenticatedEncryptionModeGCM];
479
480
481 SFAuthenticatedCiphertext* ciphertext = [op encrypt:nsdata withKey:key.key error:&error];
482
483 if(error || !ciphertext || !out_der || !out_der_len) {
484 return kAKSReturnError;
485 }
486
487 NSData* cipherBytes = [NSKeyedArchiver archivedDataWithRootObject:ciphertext requiringSecureCoding:YES error:&error];
488 if(error || !cipherBytes) {
489 return kAKSReturnError;
490 }
491
492 *out_der = calloc(1, cipherBytes.length);
493
494 memcpy(*out_der, cipherBytes.bytes, cipherBytes.length);
495 *out_der_len = cipherBytes.length;
496
497 return kAKSReturnSuccess;
498 }
499
500 int
501 aks_ref_key_decrypt(aks_ref_key_t handle,
502 const uint8_t *der_params, size_t der_params_len,
503 const void * data, size_t data_len,
504 void ** out_der, size_t * out_der_len)
505 {
506 @autoreleasepool {
507 [SecMockAKS trapdoor];
508
509 NSError *error = [SecMockAKS popDecryptRefKeyFailure];
510 if (error) {
511 return (int)error.code;
512 }
513
514 if (!out_der || !out_der_len || !data) {
515 return kAKSReturnError;
516 }
517
518 if (der_params) {
519 NSData *paramsData = [NSData dataWithBytes:der_params length:der_params_len];
520 MockAKSOptionalParameters *params = [[MockAKSOptionalParameters alloc] initWithData:paramsData];
521
522 if (params.hasExternalData && !params.hasAcmHandle) {
523 return kSKSReturnPolicyInvalid;
524 }
525 (void)params; /* check ACM context if the item uses policy */
526 }
527
528
529 NSData* nsdata = [NSData dataWithBytes:data length:data_len];
530
531 MockAKSRefKeyObject* key = (__bridge MockAKSRefKeyObject*)handle;
532
533 SFAuthenticatedCiphertext* ciphertext = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:nsdata error:&error];
534
535 if(error || !ciphertext) {
536 return kAKSReturnDecodeError;
537 }
538
539 // this should not be needed...
540 if (![ciphertext isKindOfClass:[SFAuthenticatedCiphertext class]]) {
541 return kAKSReturnDecodeError;
542 }
543 if (![ciphertext.ciphertext isKindOfClass:[NSData class]]) {
544 return kAKSReturnDecodeError;
545 }
546 if (![ciphertext.authenticationCode isKindOfClass:[NSData class]]) {
547 return kAKSReturnDecodeError;
548 }
549 if (![ciphertext.initializationVector isKindOfClass:[NSData class]]) {
550 return kAKSReturnDecodeError;
551 }
552
553 NSData* plaintext = NULL;
554
555 SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:key.key.keySpecifier authenticationMode:SFAuthenticatedEncryptionModeGCM];
556 plaintext = [op decrypt:ciphertext withKey:key.key error:&error];
557
558 if(error || !plaintext) {
559 return kAKSReturnDecodeError;
560 }
561
562 /*
563 * AAAAAAAAHHHHHHHHH
564 * The output of aks_ref_key_encrypt is not the decrypted data, it's a DER blob that contains an octet string of the data....
565 */
566
567 CFErrorRef cfError = NULL;
568 NSData* derData = (__bridge_transfer NSData*)CFPropertyListCreateDERData(NULL, (__bridge CFTypeRef)plaintext, &cfError);
569 CFReleaseNull(cfError);
570 if (derData == NULL) {
571 return kAKSReturnDecodeError;
572 }
573
574 *out_der = calloc(1, derData.length);
575 if (*out_der == NULL) {
576 abort();
577 }
578
579 memcpy(*out_der, derData.bytes, derData.length);
580 *out_der_len = derData.length;
581
582 return kAKSReturnSuccess;
583 }
584 }
585
586 int aks_ref_key_wrap(aks_ref_key_t handle,
587 uint8_t *der_params, size_t der_params_len,
588 const uint8_t *key, size_t key_len,
589 void **out_der, size_t *out_der_len)
590 {
591 [SecMockAKS trapdoor];
592
593 return aks_ref_key_encrypt(handle, der_params, der_params_len, key, key_len, out_der, out_der_len);
594 }
595
596 int aks_ref_key_unwrap(aks_ref_key_t handle,
597 uint8_t *der_params, size_t der_params_len,
598 const uint8_t *wrapped, size_t wrapped_len,
599 void **out_der, size_t *out_der_len)
600 {
601 [SecMockAKS trapdoor];
602
603 return aks_ref_key_decrypt(handle, der_params, der_params_len, wrapped, wrapped_len, out_der, out_der_len);
604 }
605
606
607 int
608 aks_ref_key_delete(aks_ref_key_t handle, const uint8_t *der_params, size_t der_params_len)
609 {
610 return kAKSReturnSuccess;
611 }
612
613 int
614 aks_operation_optional_params(const uint8_t * access_groups, size_t access_groups_len, const uint8_t * external_data, size_t external_data_len, const void * acm_handle, int acm_handle_len, void ** out_der, size_t * out_der_len)
615 {
616 @autoreleasepool {
617 [SecMockAKS trapdoor];
618
619 MockAKSOptionalParameters* params = [[MockAKSOptionalParameters alloc] init];
620
621 if (access_groups) {
622 params.accessGroups = [NSData dataWithBytes:access_groups length:access_groups_len];
623 }
624 if (external_data) {
625 params.externalData = [NSData dataWithBytes:external_data length:external_data_len];
626 }
627 if (acm_handle) {
628 params.acmHandle = [NSData dataWithBytes:acm_handle length:acm_handle_len];
629 }
630
631 NSData *result = params.data;
632 *out_der = malloc(result.length);
633 memcpy(*out_der, result.bytes, result.length);
634 *out_der_len = result.length;
635 return kAKSReturnSuccess;
636 }
637 }
638
639 int aks_ref_key_create_with_blob(keybag_handle_t keybag, const uint8_t *ref_key_blob, size_t ref_key_blob_len, aks_ref_key_t* handle)
640 {
641 NSError *error = NULL;
642 MockAKSRefKeyObject *key = NULL;
643
644 @autoreleasepool {
645 [SecMockAKS trapdoor];
646 NSData *data = [NSData dataWithBytes:ref_key_blob length:ref_key_blob_len];
647
648 MockAKSRefKey *blob = [[MockAKSRefKey alloc] initWithData:data];
649 if (blob == NULL) {
650 return kAKSReturnBadData;
651 }
652 if (!blob.hasKey || blob.key.length == 0) {
653 return kAKSReturnBadData;
654 }
655
656 key = [[MockAKSRefKeyObject alloc] initWithKeyData:blob.key parameters:blob.optionalParams error:&error];
657 }
658 if (key == NULL) {
659 *handle = (aks_ref_key_t)-1;
660 if (error.code) {
661 return (int)error.code;
662 }
663 return kAKSReturnError;
664 }
665
666 *handle = (__bridge_retained aks_ref_key_t)key;
667 return kAKSReturnSuccess;
668 }
669
670 const uint8_t * aks_ref_key_get_blob(aks_ref_key_t refkey, size_t *out_blob_len)
671 {
672 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)refkey;
673
674 *out_blob_len = key.blob.length;
675 return (const uint8_t *)key.blob.bytes;
676 }
677
678 int
679 aks_ref_key_free(aks_ref_key_t* refkey)
680 {
681 if (*refkey != NULL) {
682 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)*refkey;
683 CFTypeRef cfkey = CFBridgingRetain(key);
684 CFRelease(cfkey);
685 *refkey = NULL;
686 }
687 return kAKSReturnSuccess;
688 }
689
690 const uint8_t *
691 aks_ref_key_get_external_data(aks_ref_key_t refkey, size_t *out_external_data_len)
692 {
693 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)refkey;
694
695 *out_external_data_len = key.externalData.length;
696 return (const uint8_t *)key.externalData.bytes;
697 }
698
699 kern_return_t
700 aks_assert_hold(keybag_handle_t handle, uint32_t type, uint64_t timeout)
701 {
702 if ([SecMockAKS isLocked:key_class_ak]) {
703 return kAKSReturnNoPermission;
704 }
705 return kAKSReturnSuccess;
706 }
707
708 kern_return_t
709 aks_assert_drop(keybag_handle_t handle, uint32_t type)
710 {
711 return kAKSReturnSuccess;
712 }
713
714 kern_return_t
715 aks_generation(keybag_handle_t handle,
716 generation_option_t generation_option,
717 uint32_t * current_generation)
718 {
719 *current_generation = 0;
720 return kAKSReturnSuccess;
721 }
722
723 CFStringRef kMKBDeviceModeMultiUser = CFSTR("kMKBDeviceModeMultiUser");
724 CFStringRef kMKBDeviceModeSingleUser = CFSTR("kMKBDeviceModeSingleUser");
725 CFStringRef kMKBDeviceModeKey = CFSTR("kMKBDeviceModeKey");
726
727 static CFStringRef staticKeybagHandle = CFSTR("keybagHandle");
728
729 int
730 MKBKeyBagCreateWithData(CFDataRef keybagBlob, MKBKeyBagHandleRef* newHandle)
731 {
732 *newHandle = (MKBKeyBagHandleRef)staticKeybagHandle;
733 return kMobileKeyBagSuccess;
734 }
735
736 int
737 MKBKeyBagUnlock(MKBKeyBagHandleRef keybag, CFDataRef passcode)
738 {
739 if (keybag == NULL || !CFEqual(keybag, staticKeybagHandle)) {
740 abort();
741 }
742 return kMobileKeyBagSuccess;
743 }
744
745 int MKBKeyBagGetAKSHandle(MKBKeyBagHandleRef keybag, int32_t *handle)
746 {
747 if (keybag == NULL || !CFEqual(keybag, staticKeybagHandle)) {
748 abort();
749 }
750 *handle = 17;
751 return kMobileKeyBagSuccess;
752 }
753
754 int MKBGetDeviceLockState(CFDictionaryRef options)
755 {
756 if ([SecMockAKS isLocked:key_class_ak]) {
757 return kMobileKeyBagDeviceIsLocked;
758 }
759 return kMobileKeyBagDeviceIsUnlocked;
760 }
761
762 CF_RETURNS_RETAINED CFDictionaryRef
763 MKBUserTypeDeviceMode(CFDictionaryRef options, CFErrorRef * error)
764 {
765 return CFBridgingRetain(@{
766 (__bridge NSString *)kMKBDeviceModeKey : (__bridge NSString *)kMKBDeviceModeSingleUser,
767 });
768 }
769
770 int MKBForegroundUserSessionID( CFErrorRef * error)
771 {
772 return kMobileKeyBagSuccess;
773 }
774
775 const CFTypeRef kAKSKeyAcl = (CFTypeRef)CFSTR("kAKSKeyAcl");
776 const CFTypeRef kAKSKeyAclParamRequirePasscode = (CFTypeRef)CFSTR("kAKSKeyAclParamRequirePasscode");
777
778 const CFTypeRef kAKSKeyOpDefaultAcl = (CFTypeRef)CFSTR("kAKSKeyOpDefaultAcl");
779 const CFTypeRef kAKSKeyOpEncrypt = (CFTypeRef)CFSTR("kAKSKeyOpEncrypt");
780 const CFTypeRef kAKSKeyOpDecrypt = (CFTypeRef)CFSTR("kAKSKeyOpDecrypt");
781 const CFTypeRef kAKSKeyOpSync = (CFTypeRef)CFSTR("kAKSKeyOpSync");
782 const CFTypeRef kAKSKeyOpDelete = (CFTypeRef)CFSTR("kAKSKeyOpDelete");
783 const CFTypeRef kAKSKeyOpCreate = (CFTypeRef)CFSTR("kAKSKeyOpCreate");
784 const CFTypeRef kAKSKeyOpSign = (CFTypeRef)CFSTR("kAKSKeyOpSign");
785 const CFTypeRef kAKSKeyOpSetKeyClass = (CFTypeRef)CFSTR("kAKSKeyOpSetKeyClass");
786 const CFTypeRef kAKSKeyOpWrap = (CFTypeRef)CFSTR("kAKSKeyOpWrap");
787 const CFTypeRef kAKSKeyOpUnwrap = (CFTypeRef)CFSTR("kAKSKeyOpUnwrap");
788 const CFTypeRef kAKSKeyOpComputeKey = (CFTypeRef)CFSTR("kAKSKeyOpComputeKey");
789 const CFTypeRef kAKSKeyOpAttest = (CFTypeRef)CFSTR("kAKSKeyOpAttest");
790 const CFTypeRef kAKSKeyOpTranscrypt = (CFTypeRef)CFSTR("kAKSKeyOpTranscrypt");
791 const CFTypeRef kAKSKeyOpECIESEncrypt = (CFTypeRef)CFSTR("kAKSKeyOpECIESEncrypt");
792 const CFTypeRef kAKSKeyOpECIESDecrypt = (CFTypeRef)CFSTR("kAKSKeyOpECIESDecrypt");
793 const CFTypeRef kAKSKeyOpECIESTranscode = (CFTypeRef)CFSTR("kAKSKeyOpECIESTranscode");
794
795
796 TKTokenRef TKTokenCreate(CFDictionaryRef attributes, CFErrorRef *error)
797 {
798 return NULL;
799 }
800
801 CFTypeRef TKTokenCopyObjectData(TKTokenRef token, CFDataRef objectID, CFErrorRef *error)
802 {
803 return NULL;
804 }
805
806 CFDataRef TKTokenCreateOrUpdateObject(TKTokenRef token, CFDataRef objectID, CFMutableDictionaryRef attributes, CFErrorRef *error)
807 {
808 return NULL;
809 }
810
811 CFDataRef TKTokenCopyObjectAccessControl(TKTokenRef token, CFDataRef objectID, CFErrorRef *error)
812 {
813 return NULL;
814 }
815 bool TKTokenDeleteObject(TKTokenRef token, CFDataRef objectID, CFErrorRef *error)
816 {
817 return false;
818 }
819
820 CFDataRef TKTokenCopyPublicKeyData(TKTokenRef token, CFDataRef objectID, CFErrorRef *error)
821 {
822 return NULL;
823 }
824
825 CFTypeRef TKTokenCopyOperationResult(TKTokenRef token, CFDataRef objectID, CFIndex secKeyOperationType, CFArrayRef algorithm,
826 CFIndex secKeyOperationMode, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error)
827 {
828 return NULL;
829 }
830
831 CF_RETURNS_RETAINED CFDictionaryRef TKTokenControl(TKTokenRef token, CFDictionaryRef attributes, CFErrorRef *error)
832 {
833 return NULL;
834 }
835
836 CFTypeRef LACreateNewContextWithACMContext(CFDataRef acmContext, CFErrorRef *error)
837 {
838 return NULL;
839 }
840
841 CFDataRef LACopyACMContext(CFTypeRef context, CFErrorRef *error)
842 {
843 return NULL;
844 }
845
846 bool LAEvaluateAndUpdateACL(CFTypeRef context, CFDataRef acl, CFTypeRef operation, CFDictionaryRef hints, CFDataRef *updatedACL, CFErrorRef *error)
847 {
848 return false;
849 }
850
851 ACMContextRef
852 ACMContextCreateWithExternalForm(const void *externalForm, size_t dataLength)
853 {
854 return NULL;
855 }
856
857 ACMStatus
858 ACMContextDelete(ACMContextRef context, bool destroyContext)
859 {
860 return kACMErrorSuccess;
861 }
862
863 ACMStatus
864 ACMContextRemovePassphraseCredentialsByPurposeAndScope(const ACMContextRef context, ACMPassphrasePurpose purpose, ACMScope scope)
865 {
866 return kACMErrorSuccess;
867 }
868
869 #endif // TARGET_OS_BRIDGE