]> git.saurik.com Git - apple/security.git/blob - tests/secdmockaks/mockaks.m
Security-59754.80.3.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 #include "utilities/simulatecrash_assert.h"
56
57 bool hwaes_key_available(void)
58 {
59 return false;
60 }
61
62 #define SET_FLAG_ON(v, flag) v |= (flag)
63 #define SET_FLAG_OFF(v, flag) v &= ~(flag)
64
65 @interface SecMockAKS ()
66 @property (class, readonly) NSMutableDictionary<NSNumber*, NSNumber*>* lockedStates;
67 @property (class, readonly) dispatch_queue_t mutabilityQueue;
68 @end
69
70 @implementation SecMockAKS
71 static NSMutableDictionary* _lockedStates = nil;
72 static dispatch_queue_t _mutabilityQueue = nil;
73 static keybag_state_t _keybag_state = keybag_state_unlocked | keybag_state_been_unlocked;
74 static NSMutableArray<NSError *>* _decryptRefKeyErrors = nil;
75 static int _operationsUntilUnlock = -1; // -1: don't care, 0: be unlocked, posnum: decrement and be locked
76
77 /*
78 * Method that limit where this rather in-secure version of AKS can run
79 */
80
81 + (void)trapdoor {
82 static dispatch_once_t onceToken;
83 dispatch_once(&onceToken, ^{
84 #if DEBUG || TARGET_OS_SIMULATOR
85 return;
86 #else
87 const char *argv0 = getprogname();
88
89 if (strcmp(argv0, "securityd") == 0 || strcmp(argv0, "secd") == 0) {
90 abort();
91 }
92 if (os_variant_has_internal_content("securityd")) {
93 return;
94 }
95 #if TARGET_OS_IPHONE /* all three platforms: ios, watch, tvos */
96 if (os_variant_uses_ephemeral_storage("securityd")) {
97 return;
98 }
99 if (os_variant_allows_internal_security_policies("securityd")) {
100 return;
101 }
102 abort();
103 #endif /* TARGET_OS_IPHONE */
104 #endif /* !DEBUG || !TARGET_OS_SIMULATOR */
105 });
106 }
107
108 + (NSMutableDictionary*)lockedStates
109 {
110 if(_lockedStates == nil) {
111 _lockedStates = [NSMutableDictionary dictionary];
112 }
113 return _lockedStates;
114 }
115
116 + (dispatch_queue_t)mutabilityQueue
117 {
118 static dispatch_once_t onceToken;
119 dispatch_once(&onceToken, ^{
120 _mutabilityQueue = dispatch_queue_create("SecMockAKS", DISPATCH_QUEUE_SERIAL);
121 });
122 return _mutabilityQueue;
123 }
124
125 + (keybag_state_t)keybag_state
126 {
127 return _keybag_state;
128 }
129
130 + (void)setKeybag_state:(keybag_state_t)keybag_state
131 {
132 _keybag_state = keybag_state;
133 }
134
135 + (void)reset
136 {
137 dispatch_sync(self.mutabilityQueue, ^{
138 [self.lockedStates removeAllObjects];
139 self.keybag_state = keybag_state_unlocked;
140 });
141 }
142
143 + (bool)isLocked:(keyclass_t)key_class
144 {
145 __block bool isLocked = false;
146 dispatch_sync(self.mutabilityQueue, ^{
147 NSNumber* key = [NSNumber numberWithInt:key_class];
148 isLocked = [self.lockedStates[key] boolValue];
149 });
150 return isLocked;
151 }
152
153 + (bool)isSEPDown
154 {
155 return false;
156 }
157
158 + (bool)useGenerationCount
159 {
160 return false;
161 }
162
163 + (void)lockClassA
164 {
165 dispatch_sync(self.mutabilityQueue, ^{
166 self.lockedStates[[NSNumber numberWithInt:key_class_a]] = [NSNumber numberWithBool:YES];
167 self.lockedStates[[NSNumber numberWithInt:key_class_ak]] = [NSNumber numberWithBool:YES];
168 self.lockedStates[[NSNumber numberWithInt:key_class_aku]] = [NSNumber numberWithBool:YES];
169 self.lockedStates[[NSNumber numberWithInt:key_class_akpu]] = [NSNumber numberWithBool:YES];
170
171 SET_FLAG_ON(self.keybag_state, keybag_state_locked);
172 SET_FLAG_OFF(self.keybag_state, keybag_state_unlocked);
173 // don't touch keybag_state_been_unlocked; leave it as-is
174 });
175 }
176
177 // Simulate device being in "before first unlock"
178 + (void)lockClassA_C
179 {
180 dispatch_sync(self.mutabilityQueue, ^{
181 self.lockedStates[[NSNumber numberWithInt:key_class_a]] = [NSNumber numberWithBool:YES];
182 self.lockedStates[[NSNumber numberWithInt:key_class_ak]] = [NSNumber numberWithBool:YES];
183 self.lockedStates[[NSNumber numberWithInt:key_class_aku]] = [NSNumber numberWithBool:YES];
184 self.lockedStates[[NSNumber numberWithInt:key_class_akpu]] = [NSNumber numberWithBool:YES];
185 self.lockedStates[[NSNumber numberWithInt:key_class_c]] = [NSNumber numberWithBool:YES];
186 self.lockedStates[[NSNumber numberWithInt:key_class_ck]] = [NSNumber numberWithBool:YES];
187 self.lockedStates[[NSNumber numberWithInt:key_class_cku]] = [NSNumber numberWithBool:YES];
188
189 SET_FLAG_ON(self.keybag_state, keybag_state_locked);
190 SET_FLAG_OFF(self.keybag_state, keybag_state_unlocked);
191 SET_FLAG_OFF(self.keybag_state, keybag_state_been_unlocked);
192 });
193 }
194
195 + (void)unlockAllClasses
196 {
197 dispatch_sync(self.mutabilityQueue, ^{
198 [self.lockedStates removeAllObjects];
199
200 SET_FLAG_OFF(self.keybag_state, keybag_state_locked);
201 SET_FLAG_ON(self.keybag_state, keybag_state_unlocked);
202 SET_FLAG_ON(self.keybag_state, keybag_state_been_unlocked);
203 });
204 }
205
206 + (void)failNextDecryptRefKey: (NSError* _Nonnull) decryptRefKeyError {
207 if (_decryptRefKeyErrors == NULL) {
208 _decryptRefKeyErrors = [NSMutableArray array];
209 }
210 @synchronized(_decryptRefKeyErrors) {
211 [_decryptRefKeyErrors addObject: decryptRefKeyError];
212 }
213 }
214
215 + (NSError * _Nullable)popDecryptRefKeyFailure {
216 NSError* error = nil;
217 if (_decryptRefKeyErrors == NULL) {
218 return nil;
219 }
220 @synchronized(_decryptRefKeyErrors) {
221 if(_decryptRefKeyErrors.count > 0) {
222 error = _decryptRefKeyErrors[0];
223 [_decryptRefKeyErrors removeObjectAtIndex:0];
224 }
225 }
226 return error;
227 }
228
229 + (void)setOperationsUntilUnlock:(int)val {
230 _operationsUntilUnlock = val;
231 }
232
233 + (void)updateOperationsUntilUnlock {
234 if (_operationsUntilUnlock == -1) {
235 return;
236 }
237
238 if (_operationsUntilUnlock == 0) {
239 _operationsUntilUnlock = -1;
240 [SecMockAKS unlockAllClasses];
241 return;
242 }
243
244 --_operationsUntilUnlock;
245 }
246
247
248 @end
249
250 kern_return_t
251 aks_load_bag(const void * data, int length, keybag_handle_t* handle)
252 {
253 *handle = 17;
254 return 0;
255 }
256
257 kern_return_t
258 aks_create_bag(const void * passcode, int length, keybag_type_t type, keybag_handle_t* handle)
259 {
260 [SecMockAKS unlockAllClasses];
261 *handle = 17;
262 return 0;
263 }
264
265 kern_return_t
266 aks_unload_bag(keybag_handle_t handle)
267 {
268 return kAKSReturnSuccess;
269 }
270
271 kern_return_t
272 aks_save_bag(keybag_handle_t handle, void ** data, int * length)
273 {
274 assert(handle != bad_keybag_handle);
275 assert(data);
276 assert(length);
277
278 *data = calloc(1, 12);
279 memcpy(*data, "keybag dump", 12);
280 *length = 12;
281
282 return kAKSReturnSuccess;
283 }
284
285 kern_return_t
286 aks_get_system(keybag_handle_t special_handle, keybag_handle_t *handle)
287 {
288 *handle = 17;
289 return kAKSReturnSuccess;
290 }
291
292 kern_return_t
293 aks_get_bag_uuid(keybag_handle_t handle, uuid_t uuid)
294 {
295 memcpy(uuid, "0123456789abcdf", sizeof(uuid_t));
296 return kAKSReturnSuccess;
297 }
298
299 kern_return_t aks_lock_bag(keybag_handle_t handle)
300 {
301 if (handle == KEYBAG_DEVICE) {
302 [SecMockAKS lockClassA];
303 }
304 return kAKSReturnSuccess;
305 }
306
307 kern_return_t aks_unlock_bag(keybag_handle_t handle, const void *passcode, int length)
308 {
309 if (handle == KEYBAG_DEVICE) {
310 [SecMockAKS unlockAllClasses];
311 }
312 return kAKSReturnSuccess;
313 }
314
315 kern_return_t aks_get_lock_state(keybag_handle_t handle, keybag_state_t *state)
316 {
317 *state = SecMockAKS.keybag_state;
318 return kAKSReturnSuccess;
319 }
320
321 //static uint8_t staticAKSKey[32] = "1234567890123456789012";
322
323 #define PADDINGSIZE 8
324
325 kern_return_t
326 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)
327 {
328 [SecMockAKS trapdoor];
329
330 if ([SecMockAKS isSEPDown]) {
331 return kAKSReturnBusy;
332 }
333
334 [SecMockAKS updateOperationsUntilUnlock];
335
336 // Assumes non-device keybags are asym
337 if ([SecMockAKS isLocked:key_class] && handle == KEYBAG_DEVICE) {
338 return kAKSReturnNoPermission;
339 }
340
341 if (class_out) { // Not a required parameter
342 *class_out = key_class;
343 if ([SecMockAKS useGenerationCount]) {
344 *class_out |= (key_class_last + 1);
345 }
346 }
347
348 if (key_size > APPLE_KEYSTORE_MAX_KEY_LEN) {
349 abort();
350 }
351 if (handle != KEYBAG_DEVICE) { // For now assumes non-device bags are asym
352 if (APPLE_KEYSTORE_MAX_ASYM_WRAPPED_KEY_LEN > *wrapped_key_size_inout) {
353 abort();
354 }
355 } else {
356 if (APPLE_KEYSTORE_MAX_SYM_WRAPPED_KEY_LEN > *wrapped_key_size_inout) {
357 abort();
358 }
359 }
360
361 *wrapped_key_size_inout = key_size + PADDINGSIZE;
362 memcpy(wrapped_key, key, key_size);
363 memset(((uint8_t *)wrapped_key) + key_size, 0xff, PADDINGSIZE);
364 return kAKSReturnSuccess;
365 }
366
367 kern_return_t
368 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)
369 {
370 [SecMockAKS trapdoor];
371
372 if ([SecMockAKS isSEPDown]) {
373 return kAKSReturnBusy;
374 }
375
376 [SecMockAKS updateOperationsUntilUnlock];
377
378 if ([SecMockAKS isLocked:key_class]) {
379 return kAKSReturnNoPermission;
380 }
381
382 if (wrapped_key_size < PADDINGSIZE) {
383 abort();
384 }
385 static const char expected_padding[PADDINGSIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
386 if (memcmp(((const uint8_t *)wrapped_key) + (wrapped_key_size - PADDINGSIZE), expected_padding, PADDINGSIZE) != 0) {
387 return kAKSReturnDecodeError;
388 }
389 if (*key_size_inout < wrapped_key_size - PADDINGSIZE) {
390 abort();
391 }
392 *key_size_inout = wrapped_key_size - PADDINGSIZE;
393 memcpy(key, wrapped_key, *key_size_inout);
394
395 return kAKSReturnSuccess;
396 }
397
398 @interface MockAKSRefKeyObject: NSObject
399 @property NSData *keyData;
400 @property SFAESKey *key;
401 @property NSData *acmHandle;
402 @property NSData *externalData;
403
404 @property NSData *blob; // blob is exteralized format
405
406 - (instancetype)init NS_UNAVAILABLE;
407 - (instancetype)initWithKeyData:(NSData *)keyData parameters:(NSData *)parameters error:(NSError **)error;
408
409 @end
410 @implementation MockAKSRefKeyObject
411
412 - (instancetype)initWithKeyData:(NSData *)keyData
413 parameters:(NSData *)parameters
414 error:(NSError **)error
415 {
416 if ((self = [super init]) != NULL) {
417
418 self.keyData = [keyData copy];
419 SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize: SFAESKeyBitSize256];
420 @try {
421 self.key = [[SFAESKey alloc] initWithData:self.keyData specifier:keySpecifier error:error];
422 if (self.key == NULL) {
423 return NULL;
424 }
425 } @catch (NSException *exception) {
426 *error = [NSError errorWithDomain:@"foo" code:kAKSReturnBadArgument userInfo:nil];
427 return NULL;
428 }
429
430 MockAKSOptionalParameters *params = [[MockAKSOptionalParameters alloc] initWithData:parameters];
431
432 // enforce that the extra data is DER like
433 if (params.externalData) {
434 CFTypeRef cf = NULL;
435 CFErrorRef cferror = NULL;
436 uint8_t *der = (uint8_t *)params.externalData.bytes;
437 der_decode_plist(NULL, &cf, &cferror, der, der + params.externalData.length);
438 if (cf == NULL) {
439 *error = [NSError errorWithDomain:@"foo" code:kAKSReturnBadArgument userInfo:nil];
440 return NULL;
441 }
442 CFReleaseNull(cf);
443 }
444
445
446 self.externalData = params.externalData;
447 self.acmHandle = params.acmHandle;
448
449 MockAKSRefKey *blob = [[MockAKSRefKey alloc] init];
450 blob.key = self.keyData;
451 blob.optionalParams = parameters;
452 self.blob = blob.data;
453 }
454 return self;
455 }
456
457 @end
458
459 int
460 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)
461 {
462 MockAKSRefKeyObject *key;
463 @autoreleasepool {
464 [SecMockAKS trapdoor];
465 NSError *error = NULL;
466
467 if ([SecMockAKS isLocked:key_class]) {
468 return kAKSReturnNoPermission;
469 }
470
471 NSData *keyData = [NSData dataWithBytes:"1234567890123456789012345678901" length:32];
472 NSData *parameters = NULL;
473 if (params && params_len != 0) {
474 parameters = [NSData dataWithBytes:params length:params_len];
475 }
476
477 key = [[MockAKSRefKeyObject alloc] initWithKeyData:keyData parameters:parameters error:&error];
478 if(key == NULL) {
479 if (error) {
480 return (int)error.code;
481 }
482 return kAKSReturnError;
483 }
484 }
485
486 *ot = (__bridge_retained aks_ref_key_t)key;
487 return kAKSReturnSuccess;
488 }
489
490 int
491 aks_ref_key_encrypt(aks_ref_key_t handle,
492 const uint8_t *der_params, size_t der_params_len,
493 const void * data, size_t data_len,
494 void ** out_der, size_t * out_der_len)
495 {
496 [SecMockAKS trapdoor];
497
498 // No current error injection
499 NSError* error = nil;
500 NSData* nsdata = [NSData dataWithBytes:data length:data_len];
501
502 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)handle;
503
504 SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:key.key.keySpecifier authenticationMode:SFAuthenticatedEncryptionModeGCM];
505
506
507 SFAuthenticatedCiphertext* ciphertext = [op encrypt:nsdata withKey:key.key error:&error];
508
509 if(error || !ciphertext || !out_der || !out_der_len) {
510 return kAKSReturnError;
511 }
512
513 NSData* cipherBytes = [NSKeyedArchiver archivedDataWithRootObject:ciphertext requiringSecureCoding:YES error:&error];
514 if(error || !cipherBytes) {
515 return kAKSReturnError;
516 }
517
518 *out_der = calloc(1, cipherBytes.length);
519
520 memcpy(*out_der, cipherBytes.bytes, cipherBytes.length);
521 *out_der_len = cipherBytes.length;
522
523 return kAKSReturnSuccess;
524 }
525
526 int
527 aks_ref_key_decrypt(aks_ref_key_t handle,
528 const uint8_t *der_params, size_t der_params_len,
529 const void * data, size_t data_len,
530 void ** out_der, size_t * out_der_len)
531 {
532 @autoreleasepool {
533 [SecMockAKS trapdoor];
534
535 NSError *error = [SecMockAKS popDecryptRefKeyFailure];
536 if (error) {
537 return (int)error.code;
538 }
539
540 if (!out_der || !out_der_len || !data) {
541 return kAKSReturnError;
542 }
543
544 if (der_params) {
545 NSData *paramsData = [NSData dataWithBytes:der_params length:der_params_len];
546 MockAKSOptionalParameters *params = [[MockAKSOptionalParameters alloc] initWithData:paramsData];
547
548 if (params.hasExternalData && !params.hasAcmHandle) {
549 return kSKSReturnPolicyInvalid;
550 }
551 (void)params; /* check ACM context if the item uses policy */
552 }
553
554
555 NSData* nsdata = [NSData dataWithBytes:data length:data_len];
556
557 MockAKSRefKeyObject* key = (__bridge MockAKSRefKeyObject*)handle;
558
559 SFAuthenticatedCiphertext* ciphertext = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:nsdata error:&error];
560
561 if(error || !ciphertext) {
562 return kAKSReturnDecodeError;
563 }
564
565 // this should not be needed...
566 if (![ciphertext isKindOfClass:[SFAuthenticatedCiphertext class]]) {
567 return kAKSReturnDecodeError;
568 }
569 if (![ciphertext.ciphertext isKindOfClass:[NSData class]]) {
570 return kAKSReturnDecodeError;
571 }
572 if (![ciphertext.authenticationCode isKindOfClass:[NSData class]]) {
573 return kAKSReturnDecodeError;
574 }
575 if (![ciphertext.initializationVector isKindOfClass:[NSData class]]) {
576 return kAKSReturnDecodeError;
577 }
578
579 NSData* plaintext = NULL;
580
581 SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:key.key.keySpecifier authenticationMode:SFAuthenticatedEncryptionModeGCM];
582 plaintext = [op decrypt:ciphertext withKey:key.key error:&error];
583
584 if(error || !plaintext) {
585 return kAKSReturnDecodeError;
586 }
587
588 /*
589 * AAAAAAAAHHHHHHHHH
590 * 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....
591 */
592
593 CFErrorRef cfError = NULL;
594 NSData* derData = (__bridge_transfer NSData*)CFPropertyListCreateDERData(NULL, (__bridge CFTypeRef)plaintext, &cfError);
595 CFReleaseNull(cfError);
596 if (derData == NULL) {
597 return kAKSReturnDecodeError;
598 }
599
600 *out_der = calloc(1, derData.length);
601 if (*out_der == NULL) {
602 abort();
603 }
604
605 memcpy(*out_der, derData.bytes, derData.length);
606 *out_der_len = derData.length;
607
608 return kAKSReturnSuccess;
609 }
610 }
611
612 int aks_ref_key_wrap(aks_ref_key_t handle,
613 uint8_t *der_params, size_t der_params_len,
614 const uint8_t *key, size_t key_len,
615 void **out_der, size_t *out_der_len)
616 {
617 [SecMockAKS trapdoor];
618
619 return aks_ref_key_encrypt(handle, der_params, der_params_len, key, key_len, out_der, out_der_len);
620 }
621
622 int aks_ref_key_unwrap(aks_ref_key_t handle,
623 uint8_t *der_params, size_t der_params_len,
624 const uint8_t *wrapped, size_t wrapped_len,
625 void **out_der, size_t *out_der_len)
626 {
627 [SecMockAKS trapdoor];
628
629 return aks_ref_key_decrypt(handle, der_params, der_params_len, wrapped, wrapped_len, out_der, out_der_len);
630 }
631
632
633 int
634 aks_ref_key_delete(aks_ref_key_t handle, const uint8_t *der_params, size_t der_params_len)
635 {
636 return kAKSReturnSuccess;
637 }
638
639 const uint8_t *
640 aks_ref_key_get_public_key(aks_ref_key_t handle, size_t *pub_key_len)
641 {
642 static const uint8_t dummy_key[0x41] = { 0 };
643 *pub_key_len = sizeof(dummy_key);
644 return dummy_key;
645 }
646
647 int
648 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)
649 {
650 @autoreleasepool {
651 [SecMockAKS trapdoor];
652
653 MockAKSOptionalParameters* params = [[MockAKSOptionalParameters alloc] init];
654
655 if (access_groups) {
656 params.accessGroups = [NSData dataWithBytes:access_groups length:access_groups_len];
657 }
658 if (external_data) {
659 params.externalData = [NSData dataWithBytes:external_data length:external_data_len];
660 }
661 if (acm_handle) {
662 params.acmHandle = [NSData dataWithBytes:acm_handle length:acm_handle_len];
663 }
664
665 NSData *result = params.data;
666 *out_der = malloc(result.length);
667 memcpy(*out_der, result.bytes, result.length);
668 *out_der_len = result.length;
669 return kAKSReturnSuccess;
670 }
671 }
672
673 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)
674 {
675 NSError *error = NULL;
676 MockAKSRefKeyObject *key = NULL;
677
678 @autoreleasepool {
679 [SecMockAKS trapdoor];
680 NSData *data = [NSData dataWithBytes:ref_key_blob length:ref_key_blob_len];
681
682 MockAKSRefKey *blob = [[MockAKSRefKey alloc] initWithData:data];
683 if (blob == NULL) {
684 return kAKSReturnBadData;
685 }
686 if (!blob.hasKey || blob.key.length == 0) {
687 return kAKSReturnBadData;
688 }
689
690 key = [[MockAKSRefKeyObject alloc] initWithKeyData:blob.key parameters:blob.optionalParams error:&error];
691 }
692 if (key == NULL) {
693 *handle = (aks_ref_key_t)-1;
694 if (error.code) {
695 return (int)error.code;
696 }
697 return kAKSReturnError;
698 }
699
700 *handle = (__bridge_retained aks_ref_key_t)key;
701 return kAKSReturnSuccess;
702 }
703
704 const uint8_t * aks_ref_key_get_blob(aks_ref_key_t refkey, size_t *out_blob_len)
705 {
706 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)refkey;
707
708 *out_blob_len = key.blob.length;
709 return (const uint8_t *)key.blob.bytes;
710 }
711
712 int
713 aks_ref_key_free(aks_ref_key_t* refkey)
714 {
715 if (*refkey != NULL) {
716 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)*refkey;
717 CFTypeRef cfkey = CFBridgingRetain(key);
718 CFRelease(cfkey);
719 *refkey = NULL;
720 }
721 return kAKSReturnSuccess;
722 }
723
724 const uint8_t *
725 aks_ref_key_get_external_data(aks_ref_key_t refkey, size_t *out_external_data_len)
726 {
727 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)refkey;
728
729 *out_external_data_len = key.externalData.length;
730 return (const uint8_t *)key.externalData.bytes;
731 }
732
733 kern_return_t
734 aks_assert_hold(keybag_handle_t handle, uint32_t type, uint64_t timeout)
735 {
736 if ([SecMockAKS isLocked:key_class_ak]) {
737 return kAKSReturnNoPermission;
738 }
739 return kAKSReturnSuccess;
740 }
741
742 kern_return_t
743 aks_assert_drop(keybag_handle_t handle, uint32_t type)
744 {
745 return kAKSReturnSuccess;
746 }
747
748 kern_return_t
749 aks_generation(keybag_handle_t handle,
750 generation_option_t generation_option,
751 uint32_t * current_generation)
752 {
753 *current_generation = 0;
754 return kAKSReturnSuccess;
755 }
756
757 kern_return_t
758 aks_get_device_state(keybag_handle_t handle, aks_device_state_s *device_state)
759 {
760 // Probably not legal
761 return kAKSReturnError;
762 }
763
764 int
765 aks_system_key_get_public(aks_system_key_type_t type, aks_system_key_generation_t generation, const uint8_t *der_params, size_t der_params_len, uint8_t **pub_out, size_t *pub_len_out)
766 {
767 return kAKSReturnError;
768 }
769
770 int
771 aks_system_key_operate(aks_system_key_type_t type, aks_system_key_operation_t operation, const uint8_t *der_params, size_t der_params_len)
772 {
773 return kAKSReturnError;
774 }
775
776 int
777 aks_system_key_collection(aks_system_key_type_t type, aks_system_key_generation_t generation, const uint8_t *der_params, size_t der_params_len, uint8_t **out_der, size_t *out_der_len)
778 {
779 return kAKSReturnError;
780 }
781
782 int
783 aks_system_key_attest(aks_system_key_type_t type, aks_system_key_generation_t generation, aks_ref_key_t ref_key, const uint8_t *der_params, size_t der_params_len, uint8_t **out_der, size_t *out_der_len)
784 {
785 return kAKSReturnError;
786 }
787
788 int
789 aks_gid_attest(aks_ref_key_t handle, uint8_t *der_params, size_t der_params_len, void **out_der, size_t *out_der_len)
790 {
791 return kAKSReturnError;
792 }
793
794 int
795 aks_sik_attest(aks_ref_key_t handle, uint8_t *der_params, size_t der_params_len, void **out_der, size_t *out_der_len)
796 {
797 return kAKSReturnError;
798 }
799
800 /* Unimplemented aks_ref_key functions */
801
802 int
803 aks_ref_key_compute_key(aks_ref_key_t handle, uint8_t *der_params, size_t der_params_len, const uint8_t *pub_key, size_t pub_key_len, void **out_der, size_t *out_der_len)
804 {
805 return kAKSReturnError;
806 }
807
808 int
809 aks_ref_key_attest(aks_ref_key_t handle, uint8_t *der_params, size_t der_params_len, aks_ref_key_t handle2, void **out_der, size_t *out_der_len)
810 {
811 return kAKSReturnError;
812 }
813
814 int
815 aks_ref_key_sign(aks_ref_key_t handle, uint8_t *der_params, size_t der_params_len, const uint8_t *digest, size_t digest_len, void **out_der, size_t *out_der_len)
816 {
817 return kAKSReturnError;
818 }
819
820 int
821 aks_ref_key_ecies_transcode(aks_ref_key_t handle, uint8_t *der_params, size_t der_params_len, const uint8_t *public_key, size_t public_key_len, const uint8_t *cipher_txt_in, size_t cipher_txt_in_len, uint8_t **cipher_txt_out, size_t *cipher_txt_out_len)
822 {
823 return kAKSReturnError;
824 }
825
826 keyclass_t
827 aks_ref_key_get_key_class(aks_ref_key_t handle)
828 {
829 return key_class_a;
830 }
831
832 aks_key_type_t
833 aks_ref_key_get_type(aks_ref_key_t handle)
834 {
835 return key_type_sym;
836 }
837
838 /* AKS Params (unimplemented) */
839
840 aks_params_t aks_params_create(const uint8_t *der_params, size_t der_params_len)
841 {
842 return NULL;
843 }
844
845 int aks_params_free(aks_params_t *params)
846 {
847 return kAKSReturnSuccess;
848 }
849
850 int
851 aks_params_set_data(aks_params_t params, aks_params_key_t key, const void *value, size_t length)
852 {
853 return kAKSReturnError;
854 }
855
856 int
857 aks_params_get_der(aks_params_t params, uint8_t **out_der, size_t *out_der_len)
858 {
859 return kAKSReturnError;
860 }
861
862 int
863 aks_params_set_number(aks_params_t params, aks_params_key_t key, int64_t *num)
864 {
865 return kAKSReturnError;
866 }
867
868 // This is in libaks_internal.h, which doesn't appear to be in the SDK.
869 int aks_ref_key_enable_test_keys(keybag_handle_t handle, const uint8_t *passcode, size_t passcode_len);
870 int
871 aks_ref_key_enable_test_keys(keybag_handle_t handle, const uint8_t *passcode, size_t passcode_len)
872 {
873 abort();
874 return kAKSReturnError;
875 }
876
877 CFStringRef kMKBDeviceModeMultiUser = CFSTR("kMKBDeviceModeMultiUser");
878 CFStringRef kMKBDeviceModeSingleUser = CFSTR("kMKBDeviceModeSingleUser");
879 CFStringRef kMKBDeviceModeKey = CFSTR("kMKBDeviceModeKey");
880
881 static CFStringRef staticKeybagHandle = CFSTR("keybagHandle");
882
883 int
884 MKBKeyBagCreateWithData(CFDataRef keybagBlob, MKBKeyBagHandleRef* newHandle)
885 {
886 *newHandle = (MKBKeyBagHandleRef)staticKeybagHandle;
887 return kMobileKeyBagSuccess;
888 }
889
890 int
891 MKBKeyBagUnlock(MKBKeyBagHandleRef keybag, CFDataRef passcode)
892 {
893 if (keybag == NULL || !CFEqual(keybag, staticKeybagHandle)) {
894 abort();
895 }
896 return kMobileKeyBagSuccess;
897 }
898
899 int MKBKeyBagGetAKSHandle(MKBKeyBagHandleRef keybag, int32_t *handle)
900 {
901 if (keybag == NULL || !CFEqual(keybag, staticKeybagHandle)) {
902 abort();
903 }
904 *handle = 17;
905 return kMobileKeyBagSuccess;
906 }
907
908 int MKBGetDeviceLockState(CFDictionaryRef options)
909 {
910 if ([SecMockAKS isLocked:key_class_ak]) {
911 return kMobileKeyBagDeviceIsLocked;
912 }
913 return kMobileKeyBagDeviceIsUnlocked;
914 }
915
916 CF_RETURNS_RETAINED CFDictionaryRef
917 MKBUserTypeDeviceMode(CFDictionaryRef options, CFErrorRef * error)
918 {
919 return CFBridgingRetain(@{
920 (__bridge NSString *)kMKBDeviceModeKey : (__bridge NSString *)kMKBDeviceModeSingleUser,
921 });
922 }
923
924 int MKBForegroundUserSessionID( CFErrorRef * error)
925 {
926 return kMobileKeyBagSuccess;
927 }
928
929 ACMContextRef
930 ACMContextCreateWithExternalForm(const void *externalForm, size_t dataLength)
931 {
932 return NULL;
933 }
934
935 ACMStatus
936 ACMContextDelete(ACMContextRef context, bool destroyContext)
937 {
938 return kACMErrorSuccess;
939 }
940
941 ACMStatus
942 ACMContextRemovePassphraseCredentialsByPurposeAndScope(const ACMContextRef context, ACMPassphrasePurpose purpose, ACMScope scope)
943 {
944 return kACMErrorSuccess;
945 }
946
947 #endif // TARGET_OS_BRIDGE