2 * Copyright (c) 2018 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #import <TargetConditionals.h>
27 #import "SecKeybagSupport.h"
29 #if __has_include(<libaks.h>)
33 #if __has_include(<libaks_ref_key.h>)
34 #import <libaks_ref_key.h>
37 #if __has_include(<MobileKeyBag/MobileKeyBag.h>)
38 #import <MobileKeyBag/MobileKeyBag.h>
41 #include <os/variant_private.h>
43 #import <ctkclient/ctkclient.h>
44 #import <coreauthd_spi.h>
46 #import <LocalAuthentication/LAPublicDefines.h>
47 #import <LocalAuthentication/LAPrivateDefines.h>
48 #import <LocalAuthentication/LACFSupport.h>
49 #import <SecurityFoundation/SFEncryptionOperation.h>
51 #import "utilities/der_plist.h"
52 #import "tests/secdmockaks/generated_source/MockAKSRefKey.h"
53 #import "tests/secdmockaks/generated_source/MockAKSOptionalParameters.h"
55 #include "utilities/simulatecrash_assert.h"
57 bool hwaes_key_available(void)
62 #define SET_FLAG_ON(v, flag) v |= (flag)
63 #define SET_FLAG_OFF(v, flag) v &= ~(flag)
65 @interface SecMockAKS ()
66 @property (class, readonly) NSMutableDictionary<NSNumber*, NSNumber*>* lockedStates;
67 @property (class, readonly) dispatch_queue_t mutabilityQueue;
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
78 * Method that limit where this rather in-secure version of AKS can run
82 static dispatch_once_t onceToken;
83 dispatch_once(&onceToken, ^{
84 #if DEBUG || TARGET_OS_SIMULATOR
87 const char *argv0 = getprogname();
89 if (strcmp(argv0, "securityd") == 0 || strcmp(argv0, "secd") == 0) {
92 if (os_variant_has_internal_content("securityd")) {
95 #if TARGET_OS_IPHONE /* all three platforms: ios, watch, tvos */
96 if (os_variant_uses_ephemeral_storage("securityd")) {
99 if (os_variant_allows_internal_security_policies("securityd")) {
103 #endif /* TARGET_OS_IPHONE */
104 #endif /* !DEBUG || !TARGET_OS_SIMULATOR */
108 + (NSMutableDictionary*)lockedStates
110 if(_lockedStates == nil) {
111 _lockedStates = [NSMutableDictionary dictionary];
113 return _lockedStates;
116 + (dispatch_queue_t)mutabilityQueue
118 static dispatch_once_t onceToken;
119 dispatch_once(&onceToken, ^{
120 _mutabilityQueue = dispatch_queue_create("SecMockAKS", DISPATCH_QUEUE_SERIAL);
122 return _mutabilityQueue;
125 + (keybag_state_t)keybag_state
127 return _keybag_state;
130 + (void)setKeybag_state:(keybag_state_t)keybag_state
132 _keybag_state = keybag_state;
137 dispatch_sync(self.mutabilityQueue, ^{
138 [self.lockedStates removeAllObjects];
139 self.keybag_state = keybag_state_unlocked;
143 + (bool)isLocked:(keyclass_t)key_class
145 __block bool isLocked = false;
146 dispatch_sync(self.mutabilityQueue, ^{
147 NSNumber* key = [NSNumber numberWithInt:key_class];
148 isLocked = [self.lockedStates[key] boolValue];
158 + (bool)useGenerationCount
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];
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
177 // Simulate device being in "before first unlock"
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];
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);
195 + (void)unlockAllClasses
197 dispatch_sync(self.mutabilityQueue, ^{
198 [self.lockedStates removeAllObjects];
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);
206 + (void)failNextDecryptRefKey: (NSError* _Nonnull) decryptRefKeyError {
207 if (_decryptRefKeyErrors == NULL) {
208 _decryptRefKeyErrors = [NSMutableArray array];
210 @synchronized(_decryptRefKeyErrors) {
211 [_decryptRefKeyErrors addObject: decryptRefKeyError];
215 + (NSError * _Nullable)popDecryptRefKeyFailure {
216 NSError* error = nil;
217 if (_decryptRefKeyErrors == NULL) {
220 @synchronized(_decryptRefKeyErrors) {
221 if(_decryptRefKeyErrors.count > 0) {
222 error = _decryptRefKeyErrors[0];
223 [_decryptRefKeyErrors removeObjectAtIndex:0];
229 + (void)setOperationsUntilUnlock:(int)val {
230 _operationsUntilUnlock = val;
233 + (void)updateOperationsUntilUnlock {
234 if (_operationsUntilUnlock == -1) {
238 if (_operationsUntilUnlock == 0) {
239 _operationsUntilUnlock = -1;
240 [SecMockAKS unlockAllClasses];
244 --_operationsUntilUnlock;
251 aks_load_bag(const void * data, int length, keybag_handle_t* handle)
258 aks_create_bag(const void * passcode, int length, keybag_type_t type, keybag_handle_t* handle)
260 [SecMockAKS unlockAllClasses];
266 aks_unload_bag(keybag_handle_t handle)
268 return kAKSReturnSuccess;
272 aks_save_bag(keybag_handle_t handle, void ** data, int * length)
274 assert(handle != bad_keybag_handle);
278 *data = calloc(1, 12);
279 memcpy(*data, "keybag dump", 12);
282 return kAKSReturnSuccess;
286 aks_get_system(keybag_handle_t special_handle, keybag_handle_t *handle)
289 return kAKSReturnSuccess;
293 aks_get_bag_uuid(keybag_handle_t handle, uuid_t uuid)
295 memcpy(uuid, "0123456789abcdf", sizeof(uuid_t));
296 return kAKSReturnSuccess;
299 kern_return_t aks_lock_bag(keybag_handle_t handle)
301 if (handle == KEYBAG_DEVICE) {
302 [SecMockAKS lockClassA];
304 return kAKSReturnSuccess;
307 kern_return_t aks_unlock_bag(keybag_handle_t handle, const void *passcode, int length)
309 if (handle == KEYBAG_DEVICE) {
310 [SecMockAKS unlockAllClasses];
312 return kAKSReturnSuccess;
315 kern_return_t aks_get_lock_state(keybag_handle_t handle, keybag_state_t *state)
317 *state = SecMockAKS.keybag_state;
318 return kAKSReturnSuccess;
321 //static uint8_t staticAKSKey[32] = "1234567890123456789012";
323 #define PADDINGSIZE 8
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)
328 [SecMockAKS trapdoor];
330 if ([SecMockAKS isSEPDown]) {
331 return kAKSReturnBusy;
334 [SecMockAKS updateOperationsUntilUnlock];
336 // Assumes non-device keybags are asym
337 if ([SecMockAKS isLocked:key_class] && handle == KEYBAG_DEVICE) {
338 return kAKSReturnNoPermission;
341 if (class_out) { // Not a required parameter
342 *class_out = key_class;
343 if ([SecMockAKS useGenerationCount]) {
344 *class_out |= (key_class_last + 1);
348 if (key_size > APPLE_KEYSTORE_MAX_KEY_LEN) {
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) {
356 if (APPLE_KEYSTORE_MAX_SYM_WRAPPED_KEY_LEN > *wrapped_key_size_inout) {
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;
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)
370 [SecMockAKS trapdoor];
372 if ([SecMockAKS isSEPDown]) {
373 return kAKSReturnBusy;
376 [SecMockAKS updateOperationsUntilUnlock];
378 if ([SecMockAKS isLocked:key_class]) {
379 return kAKSReturnNoPermission;
382 if (wrapped_key_size < PADDINGSIZE) {
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;
389 if (*key_size_inout < wrapped_key_size - PADDINGSIZE) {
392 *key_size_inout = wrapped_key_size - PADDINGSIZE;
393 memcpy(key, wrapped_key, *key_size_inout);
395 return kAKSReturnSuccess;
398 @interface MockAKSRefKeyObject: NSObject
399 @property NSData *keyData;
400 @property SFAESKey *key;
401 @property NSData *acmHandle;
402 @property NSData *externalData;
404 @property NSData *blob; // blob is exteralized format
406 - (instancetype)init NS_UNAVAILABLE;
407 - (instancetype)initWithKeyData:(NSData *)keyData parameters:(NSData *)parameters error:(NSError **)error;
410 @implementation MockAKSRefKeyObject
412 - (instancetype)initWithKeyData:(NSData *)keyData
413 parameters:(NSData *)parameters
414 error:(NSError **)error
416 if ((self = [super init]) != NULL) {
418 self.keyData = [keyData copy];
419 SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize: SFAESKeyBitSize256];
421 self.key = [[SFAESKey alloc] initWithData:self.keyData specifier:keySpecifier error:error];
422 if (self.key == NULL) {
425 } @catch (NSException *exception) {
426 *error = [NSError errorWithDomain:@"foo" code:kAKSReturnBadArgument userInfo:nil];
430 MockAKSOptionalParameters *params = [[MockAKSOptionalParameters alloc] initWithData:parameters];
432 // enforce that the extra data is DER like
433 if (params.externalData) {
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);
439 *error = [NSError errorWithDomain:@"foo" code:kAKSReturnBadArgument userInfo:nil];
446 self.externalData = params.externalData;
447 self.acmHandle = params.acmHandle;
449 MockAKSRefKey *blob = [[MockAKSRefKey alloc] init];
450 blob.key = self.keyData;
451 blob.optionalParams = parameters;
452 self.blob = blob.data;
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)
462 MockAKSRefKeyObject *key;
464 [SecMockAKS trapdoor];
465 NSError *error = NULL;
467 if ([SecMockAKS isLocked:key_class]) {
468 return kAKSReturnNoPermission;
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];
477 key = [[MockAKSRefKeyObject alloc] initWithKeyData:keyData parameters:parameters error:&error];
480 return (int)error.code;
482 return kAKSReturnError;
486 *ot = (__bridge_retained aks_ref_key_t)key;
487 return kAKSReturnSuccess;
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)
496 [SecMockAKS trapdoor];
498 // No current error injection
499 NSError* error = nil;
500 NSData* nsdata = [NSData dataWithBytes:data length:data_len];
502 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)handle;
504 SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:key.key.keySpecifier authenticationMode:SFAuthenticatedEncryptionModeGCM];
507 SFAuthenticatedCiphertext* ciphertext = [op encrypt:nsdata withKey:key.key error:&error];
509 if(error || !ciphertext || !out_der || !out_der_len) {
510 return kAKSReturnError;
513 NSData* cipherBytes = [NSKeyedArchiver archivedDataWithRootObject:ciphertext requiringSecureCoding:YES error:&error];
514 if(error || !cipherBytes) {
515 return kAKSReturnError;
518 *out_der = calloc(1, cipherBytes.length);
520 memcpy(*out_der, cipherBytes.bytes, cipherBytes.length);
521 *out_der_len = cipherBytes.length;
523 return kAKSReturnSuccess;
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)
533 [SecMockAKS trapdoor];
535 NSError *error = [SecMockAKS popDecryptRefKeyFailure];
537 return (int)error.code;
540 if (!out_der || !out_der_len || !data) {
541 return kAKSReturnError;
545 NSData *paramsData = [NSData dataWithBytes:der_params length:der_params_len];
546 MockAKSOptionalParameters *params = [[MockAKSOptionalParameters alloc] initWithData:paramsData];
548 if (params.hasExternalData && !params.hasAcmHandle) {
549 return kSKSReturnPolicyInvalid;
551 (void)params; /* check ACM context if the item uses policy */
555 NSData* nsdata = [NSData dataWithBytes:data length:data_len];
557 MockAKSRefKeyObject* key = (__bridge MockAKSRefKeyObject*)handle;
559 SFAuthenticatedCiphertext* ciphertext = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:nsdata error:&error];
561 if(error || !ciphertext) {
562 return kAKSReturnDecodeError;
565 // this should not be needed...
566 if (![ciphertext isKindOfClass:[SFAuthenticatedCiphertext class]]) {
567 return kAKSReturnDecodeError;
569 if (![ciphertext.ciphertext isKindOfClass:[NSData class]]) {
570 return kAKSReturnDecodeError;
572 if (![ciphertext.authenticationCode isKindOfClass:[NSData class]]) {
573 return kAKSReturnDecodeError;
575 if (![ciphertext.initializationVector isKindOfClass:[NSData class]]) {
576 return kAKSReturnDecodeError;
579 NSData* plaintext = NULL;
581 SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:key.key.keySpecifier authenticationMode:SFAuthenticatedEncryptionModeGCM];
582 plaintext = [op decrypt:ciphertext withKey:key.key error:&error];
584 if(error || !plaintext) {
585 return kAKSReturnDecodeError;
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....
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;
600 *out_der = calloc(1, derData.length);
601 if (*out_der == NULL) {
605 memcpy(*out_der, derData.bytes, derData.length);
606 *out_der_len = derData.length;
608 return kAKSReturnSuccess;
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)
617 [SecMockAKS trapdoor];
619 return aks_ref_key_encrypt(handle, der_params, der_params_len, key, key_len, out_der, out_der_len);
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)
627 [SecMockAKS trapdoor];
629 return aks_ref_key_decrypt(handle, der_params, der_params_len, wrapped, wrapped_len, out_der, out_der_len);
634 aks_ref_key_delete(aks_ref_key_t handle, const uint8_t *der_params, size_t der_params_len)
636 return kAKSReturnSuccess;
640 aks_ref_key_get_public_key(aks_ref_key_t handle, size_t *pub_key_len)
642 static const uint8_t dummy_key[0x41] = { 0 };
643 *pub_key_len = sizeof(dummy_key);
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)
651 [SecMockAKS trapdoor];
653 MockAKSOptionalParameters* params = [[MockAKSOptionalParameters alloc] init];
656 params.accessGroups = [NSData dataWithBytes:access_groups length:access_groups_len];
659 params.externalData = [NSData dataWithBytes:external_data length:external_data_len];
662 params.acmHandle = [NSData dataWithBytes:acm_handle length:acm_handle_len];
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;
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)
675 NSError *error = NULL;
676 MockAKSRefKeyObject *key = NULL;
679 [SecMockAKS trapdoor];
680 NSData *data = [NSData dataWithBytes:ref_key_blob length:ref_key_blob_len];
682 MockAKSRefKey *blob = [[MockAKSRefKey alloc] initWithData:data];
684 return kAKSReturnBadData;
686 if (!blob.hasKey || blob.key.length == 0) {
687 return kAKSReturnBadData;
690 key = [[MockAKSRefKeyObject alloc] initWithKeyData:blob.key parameters:blob.optionalParams error:&error];
693 *handle = (aks_ref_key_t)-1;
695 return (int)error.code;
697 return kAKSReturnError;
700 *handle = (__bridge_retained aks_ref_key_t)key;
701 return kAKSReturnSuccess;
704 const uint8_t * aks_ref_key_get_blob(aks_ref_key_t refkey, size_t *out_blob_len)
706 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)refkey;
708 *out_blob_len = key.blob.length;
709 return (const uint8_t *)key.blob.bytes;
713 aks_ref_key_free(aks_ref_key_t* refkey)
715 if (*refkey != NULL) {
716 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)*refkey;
717 CFTypeRef cfkey = CFBridgingRetain(key);
721 return kAKSReturnSuccess;
725 aks_ref_key_get_external_data(aks_ref_key_t refkey, size_t *out_external_data_len)
727 MockAKSRefKeyObject *key = (__bridge MockAKSRefKeyObject*)refkey;
729 *out_external_data_len = key.externalData.length;
730 return (const uint8_t *)key.externalData.bytes;
734 aks_assert_hold(keybag_handle_t handle, uint32_t type, uint64_t timeout)
736 if ([SecMockAKS isLocked:key_class_ak]) {
737 return kAKSReturnNoPermission;
739 return kAKSReturnSuccess;
743 aks_assert_drop(keybag_handle_t handle, uint32_t type)
745 return kAKSReturnSuccess;
749 aks_generation(keybag_handle_t handle,
750 generation_option_t generation_option,
751 uint32_t * current_generation)
753 *current_generation = 0;
754 return kAKSReturnSuccess;
758 aks_get_device_state(keybag_handle_t handle, aks_device_state_s *device_state)
760 // Probably not legal
761 return kAKSReturnError;
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)
767 return kAKSReturnError;
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)
773 return kAKSReturnError;
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)
779 return kAKSReturnError;
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)
785 return kAKSReturnError;
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)
791 return kAKSReturnError;
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)
797 return kAKSReturnError;
800 /* Unimplemented aks_ref_key functions */
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)
805 return kAKSReturnError;
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)
811 return kAKSReturnError;
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)
817 return kAKSReturnError;
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)
823 return kAKSReturnError;
827 aks_ref_key_get_key_class(aks_ref_key_t handle)
833 aks_ref_key_get_type(aks_ref_key_t handle)
838 /* AKS Params (unimplemented) */
840 aks_params_t aks_params_create(const uint8_t *der_params, size_t der_params_len)
845 int aks_params_free(aks_params_t *params)
847 return kAKSReturnSuccess;
851 aks_params_set_data(aks_params_t params, aks_params_key_t key, const void *value, size_t length)
853 return kAKSReturnError;
857 aks_params_get_der(aks_params_t params, uint8_t **out_der, size_t *out_der_len)
859 return kAKSReturnError;
863 aks_params_set_number(aks_params_t params, aks_params_key_t key, int64_t *num)
865 return kAKSReturnError;
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);
871 aks_ref_key_enable_test_keys(keybag_handle_t handle, const uint8_t *passcode, size_t passcode_len)
874 return kAKSReturnError;
877 CFStringRef kMKBDeviceModeMultiUser = CFSTR("kMKBDeviceModeMultiUser");
878 CFStringRef kMKBDeviceModeSingleUser = CFSTR("kMKBDeviceModeSingleUser");
879 CFStringRef kMKBDeviceModeKey = CFSTR("kMKBDeviceModeKey");
881 static CFStringRef staticKeybagHandle = CFSTR("keybagHandle");
884 MKBKeyBagCreateWithData(CFDataRef keybagBlob, MKBKeyBagHandleRef* newHandle)
886 *newHandle = (MKBKeyBagHandleRef)staticKeybagHandle;
887 return kMobileKeyBagSuccess;
891 MKBKeyBagUnlock(MKBKeyBagHandleRef keybag, CFDataRef passcode)
893 if (keybag == NULL || !CFEqual(keybag, staticKeybagHandle)) {
896 return kMobileKeyBagSuccess;
899 int MKBKeyBagGetAKSHandle(MKBKeyBagHandleRef keybag, int32_t *handle)
901 if (keybag == NULL || !CFEqual(keybag, staticKeybagHandle)) {
905 return kMobileKeyBagSuccess;
908 int MKBGetDeviceLockState(CFDictionaryRef options)
910 if ([SecMockAKS isLocked:key_class_ak]) {
911 return kMobileKeyBagDeviceIsLocked;
913 return kMobileKeyBagDeviceIsUnlocked;
916 CF_RETURNS_RETAINED CFDictionaryRef
917 MKBUserTypeDeviceMode(CFDictionaryRef options, CFErrorRef * error)
919 return CFBridgingRetain(@{
920 (__bridge NSString *)kMKBDeviceModeKey : (__bridge NSString *)kMKBDeviceModeSingleUser,
924 int MKBForegroundUserSessionID( CFErrorRef * error)
926 return kMobileKeyBagSuccess;
930 ACMContextCreateWithExternalForm(const void *externalForm, size_t dataLength)
936 ACMContextDelete(ACMContextRef context, bool destroyContext)
938 return kACMErrorSuccess;
942 ACMContextRemovePassphraseCredentialsByPurposeAndScope(const ACMContextRef context, ACMPassphrasePurpose purpose, ACMScope scope)
944 return kACMErrorSuccess;
947 #endif // TARGET_OS_BRIDGE