]> git.saurik.com Git - apple/security.git/blobdiff - OSX/shared_regressions/si-44-seckey-aks.m
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / shared_regressions / si-44-seckey-aks.m
index 53232555ca6d64ed54d63962a47365a8d819e15f..cd8a2a465ea84266972a00457045f0e06106279d 100644 (file)
@@ -8,17 +8,13 @@
 #import <Security/SecKeyPriv.h>
 #import <Security/SecAccessControlPriv.h>
 #import <libaks_acl_cf_keys.h>
-#if !TARGET_OS_OSX
 #import "MobileGestalt.h"
-#else
-#import <RemoteServiceDiscovery/RemoteServiceDiscovery.h>
-#endif
 
 #import "shared_regressions.h"
 
-static id generateKey(id keyType, CFStringRef protection, BOOL noACL) {
+static id generateKey(id keyType, CFStringRef protection, BOOL withACL) {
     id accessControl;
-    if (noACL) {
+    if (!withACL) {
         accessControl = CFBridgingRelease(SecAccessControlCreate(kCFAllocatorDefault, NULL));
         SecAccessControlSetProtection((__bridge SecAccessControlRef)accessControl, protection, NULL);
     } else {
@@ -41,9 +37,9 @@ static void secKeySepTest(BOOL testPKA) {
     } else {
         keyTypes = @[(id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeyTypeSecureEnclaveAttestation];
     }
-    BOOL noACL = YES;
+    BOOL withACL = NO;
     for (id keyType in keyTypes) {
-        id privateKey = generateKey((id)keyType, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, (noACL = !noACL));
+        id privateKey = generateKey((id)keyType, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, (withACL = !withACL));
         ok(privateKey, "failed to create key '%@'", keyType);
         id publicKey = (__bridge_transfer id)SecKeyCopyPublicKey((SecKeyRef)privateKey);
 
@@ -92,16 +88,13 @@ static void secKeySepTest(BOOL testPKA) {
     }
 }
 
-static void attestationTest(CFStringRef protection, BOOL noACL) {
+static void attestationTest(CFStringRef protection, BOOL withACL) {
     NSError *error;
-    id privKey = generateKey((id)kSecAttrKeyTypeECSECPrimeRandom, protection, noACL);
-    id uik = generateKey((id)kSecAttrKeyTypeSecureEnclaveAttestation, protection, noACL);
+    id privKey = generateKey((id)kSecAttrKeyTypeECSECPrimeRandom, protection, withACL);
+    id uik = generateKey((id)kSecAttrKeyTypeSecureEnclaveAttestation, protection, withACL);
     id sik = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeSIK, (void *)&error));
     ok(sik != nil, "get SIK key: %@", error);
 
-    id pubSIK = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sik));
-    ok(pubSIK != nil, "get SIK pubkey");
-
     error = nil;
     NSData *attSIKPlain = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)uik, (void *)&error));
     ok(attSIKPlain != nil, "SIK attesting UIK, no nonce: %@", error);
@@ -120,80 +113,106 @@ static void attestationTest(CFStringRef protection, BOOL noACL) {
     ok(SecKeySetParameter((__bridge SecKeyRef)uik, kSecKeyParameterSETokenAttestationNonce, (__bridge CFPropertyListRef)nonce, (void *)&error), "Set nonce to UIK: %@", error);
     NSData *attUIKNonce = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)uik, (__bridge SecKeyRef)privKey, (void *)&error));
     ok(attUIKNonce != nil, "SIK attesting UIK, with nonce: %@", error);
+}
+
+static void sysKeyAttestationTest(CFStringRef protection, BOOL withACL, const char *name, SecKeyAttestationKeyType committed, SecKeyAttestationKeyType proposed, BOOL canAttest) {
+    NSError *error;
+    id privKey = generateKey((id)kSecAttrKeyTypeECSECPrimeRandom, protection, withACL);
+    id sik = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeSIK, (void *)&error));
+    ok(sik != nil, "get SIK key: %@", error);
+
+    id pubSIK = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sik));
+    ok(pubSIK != nil, "get SIK pubkey");
+
+    id sysKeyC = CFBridgingRelease(SecKeyCopyAttestationKey(committed, (void *)&error));
+    if (sysKeyC == nil) {
+        diag("skipping attestation test, platform does not support key %s-committed", name);
+        return;
+    }
 
     error = nil;
-    id sysUikC = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeUIKCommitted, (void *)&error));
-    if (sysUikC == nil) {
-        // Platform does not support system UIK, so just fake test rounds to avoid testplan counting failures.
-        for (int i = 0; i < 19; i++) {
-            ok(true);
-        }
-    } else {
-        ok(sysUikC != nil, "get UIK-committed key, error: %@", error);
-        error = nil;
-        id sysUikP = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeUIKProposed, (void *)&error));
-        ok(sysUikP != nil, "get UIK-proposed key: %@", error);
+    id sysKeyP = CFBridgingRelease(SecKeyCopyAttestationKey(proposed, (void *)&error));
+    ok(sysKeyP != nil, "unable to get proposed key, but successfully got committed key");
 
+    if (canAttest) {
         error = nil;
-        NSData *attUIKC = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error));
-        ok(attUIKC != nil, "Sys-UIK-committed attesting privKey: %@", error);
+        NSData *attSysKeyC = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysKeyC, (__bridge SecKeyRef)privKey, (void *)&error));
+        ok(attSysKeyC != nil, "%s-committed attesting privKey: %@", name, error);
 
         error = nil;
-        NSData *attUIKP = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error));
-        ok(attUIKP != nil, "Sys-UIK-proposed attesting privKey: %@", error);
+        NSData *attSysKeyP = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysKeyP, (__bridge SecKeyRef)privKey, (void *)&error));
+        ok(attSysKeyP != nil, "%s-proposed attesting privKey: %@", name, error);
+    }
 
-        id pubUIKP = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikP));
-        ok(pubUIKP != nil, "Sys-UIK-proposed copy public key");
-        id pubUIKC = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikC));
-        ok(pubUIKC != nil, "Sys-UIK-proposed copy public key");
-        ok([pubUIKP isEqual:pubUIKC], "Sys-UIK proposed and committed are same before bump");
+    id pubSysKeyP = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysKeyP));
+    ok(pubSysKeyP != nil, "%s-proposed copy public key", name);
+    id pubSysKeyC = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysKeyC));
+    ok(pubSysKeyC != nil, "%s-committed copy public key", name);
 
-        BOOL res = SecKeyControlLifetime((__bridge SecKeyRef)sysUikC, kSecKeyControlLifetimeTypeBump, (void *)&error);
-        ok(res, "bumping sys-uik: %@", error);
+    BOOL res = SecKeyControlLifetime((__bridge SecKeyRef)sysKeyC, kSecKeyControlLifetimeTypeBump, (void *)&error);
+    ok(res, "bumping %s: %@", name, error);
 
+    if (canAttest) {
         error = nil;
-        NSData *attUIKCN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error));
-        ok(attUIKCN != nil, "Sys-UIK-committed attesting privKey: %@", error);
+        NSData *attSysKeyCN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysKeyC, (__bridge SecKeyRef)privKey, (void *)&error));
+        ok(attSysKeyCN != nil, "%s-committed attesting privKey: %@", name, error);
 
         error = nil;
-        NSData *attUIKPN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error));
-        ok(attUIKPN != nil, "Sys-UIK-proposed attesting privKey: %@", error);
+        NSData *attSysKeyPN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysKeyP, (__bridge SecKeyRef)privKey, (void *)&error));
+        ok(attSysKeyPN != nil, "%s-proposed attesting privKey: %@", name, error);
+    }
 
-        id pubUIKPN = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikP));
-        ok(pubUIKPN != nil, "Sys-UIK-proposed copy public key");
-        ok(![pubUIKPN isEqual:pubUIKC], "Sys-UIK proposed and committed differ after bump");
+    id pubSysKeyPN = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysKeyP));
+    ok(pubSysKeyPN != nil, "%s-proposed copy public key", name);
+    ok(![pubSysKeyPN isEqual:pubSysKeyC], "%s proposed and committed differ after bump", name);
 
-        res = SecKeyControlLifetime((__bridge SecKeyRef)sysUikP, kSecKeyControlLifetimeTypeCommit, (void *)&error);
-        ok(res, "committing sys-uik: %@", error);
+    res = SecKeyControlLifetime((__bridge SecKeyRef)sysKeyP, kSecKeyControlLifetimeTypeCommit, (void *)&error);
+    ok(res, "committing %s: %@", name, error);
 
+    if (canAttest) {
         error = nil;
-        NSData *attUIKCNN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error));
-        ok(attUIKCNN != nil, "Sys-UIK-committed attesting privKey: %@", error);
+        NSData *attSysKeyCNN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysKeyC, (__bridge SecKeyRef)privKey, (void *)&error));
+        ok(attSysKeyCNN != nil, "%s-committed attesting privKey: %@", name, error);
 
         error = nil;
-        NSData *attUIKPNN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error));
-        ok(attUIKPNN != nil, "Sys-UIK-proposed attesting privKey: %@", error);
+        NSData *attSysKeyPNN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysKeyP, (__bridge SecKeyRef)privKey, (void *)&error));
+        ok(attSysKeyPNN != nil, "%s-proposed attesting privKey: %@", name, error);
+    }
 
-        id pubUIKCN = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikC));
-        ok(pubUIKCN != nil, "Sys-UIK-committed copy public key");
-        ok([pubUIKPN isEqual:pubUIKC], "Sys-UIK proposed and committed same after commit");
+    id pubSysKeyCN = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysKeyC));
+    ok(pubSysKeyCN != nil, "%s-committed copy public key", name);
+    ok([pubSysKeyPN isEqual:pubSysKeyCN], "%s proposed and committed same after commit", name);
 
-        // Attest system-UIK with SIK
-        NSData *attSIKUIKP = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)sysUikP, (void *)&error));
-        ok(attSIKUIKP != nil, "SIK attesting Sys-UIK-proposed, error: %@", error);
+    // Attest system key with SIK
+    NSData *attSIKSysKeyP = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)sysKeyP, (void *)&error));
+    ok(attSIKSysKeyP != nil, "SIK attesting %s-proposed, error: %@", name, error);
 
-        NSData *attSIKUIKC = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)sysUikC, (void *)&error));
-        ok(attSIKUIKC != nil, "SIK attesting Sys-UIK-committed, error: %@", error);
-    }
+    NSData *attSIKSysKeyC = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)sysKeyC, (void *)&error));
+    ok(attSIKSysKeyC != nil, "SIK attesting %s-committed, error: %@", name, error);
 }
 
-static const uint8_t satori_pub[] = {
-    0x04, 0xe4, 0xef, 0x00, 0x27, 0xcb, 0xa6, 0x46, 0x0d, 0xa6, 0xbd, 0x77, 0x14, 0x65, 0xe5, 0x5a,
-    0x14, 0xc9, 0xf8, 0xd8, 0xdd, 0x4c, 0x70, 0x44, 0x50, 0x49, 0xe4, 0xfa, 0x24, 0x71, 0xaa, 0x4c,
-    0xe2, 0x74, 0x3b, 0xfd, 0x23, 0xda, 0x6f, 0x92, 0x04, 0x4c, 0x93, 0x6c, 0xea, 0x8a, 0xac, 0x22,
-    0x99, 0xd9, 0x6e, 0x3f, 0xed, 0x20, 0xfd, 0xdd, 0x95, 0xe2, 0x32, 0xa0, 0xeb, 0x23, 0xa2, 0xd2,
-    0x8b
-};
+static void keyFromBlobTest(void) {
+    NSError *error;
+    
+    NSDictionary *keyParams = @{ (id)kSecAttrTokenID: (id)kSecAttrTokenIDAppleKeyStore,
+                                 (id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom,
+                                 (id)kSecAttrIsPermanent: @NO
+                                 };
+    id privateKeyRef = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)keyParams, (void *)&error));
+    ok(privateKeyRef != nil, "Failed to create a random key: %@", error);
+
+    NSDictionary *keyAttrs = CFBridgingRelease(SecKeyCopyAttributes((SecKeyRef)privateKeyRef));
+    NSData *keyBlob = keyAttrs[(id)kSecAttrTokenOID];
+    
+    // keyBlob -> SecKey:
+    NSDictionary *params = @{ (id)kSecAttrTokenID : (id)kSecAttrTokenIDAppleKeyStore,
+                              (id)kSecAttrTokenOID : keyBlob };
+    id newKeyRef = CFBridgingRelease(SecKeyCreateWithData((CFDataRef)keyBlob, (CFDictionaryRef)params, (void *)&error));
+    ok(newKeyRef != nil, "Failed to create key from data: %@", error);
+
+    id ref;
+    is_status(SecItemCopyMatching(((__bridge CFDictionaryRef) @{(id)kSecClass: (id)kSecClassKey, (id)kSecValueRef: newKeyRef}), (void *)&ref), errSecItemNotFound);
+}
 
 static const uint8_t satori_priv[] = {
     0x04, 0xe4, 0xef, 0x00, 0x27, 0xcb, 0xa6, 0x46,
@@ -396,34 +415,129 @@ static void rewrapTest(void) {
     ok([decrypted isEqualToData:message], "Decrypted data differs: %@ vs %@", decrypted, message);
 }
 
+static void keychainTest(void) {
+    id accessControl = CFBridgingRelease(SecAccessControlCreateWithFlags(NULL, kSecAttrAccessibleWhenUnlocked, kSecAccessControlPrivateKeyUsage, NULL));
+    NSDictionary *keyAttributes = @{ (id)kSecAttrTokenID : (id)kSecAttrTokenIDAppleKeyStore,
+                                     (id)kSecAttrKeyType : (id)kSecAttrKeyTypeECSECPrimeRandom,
+                                     (id)kSecPrivateKeyAttrs : @{
+                                             (id)kSecAttrAccessControl : accessControl,
+                                             (id)kSecAttrIsPermanent : @YES,
+                                             (id)kSecAttrLabel : @"si_44_seckey_aks_1",
+                                     },
+    };
+    NSError *error;
+    id key = (__bridge_transfer id)SecKeyCreateRandomKey((CFDictionaryRef)keyAttributes, (void *)&error);
+    ok(key, "failed to create random key %@", error);
+    id pubKey = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key));
+    ok(pubKey, "failed to get public key from SEP key");
+    key = nil;
+
+    NSDictionary *query = @{
+        (id)kSecReturnRef: @YES,
+        (id)kSecClass: (id)kSecClassKey,
+        (id)kSecAttrLabel: @"si_44_seckey_aks_1",
+    };
+    OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (void *)&key);
+    is(status, errSecSuccess, "getting SEP key from keychain failed");
+
+    NSError *err;
+    NSData *data = [@"message" dataUsingEncoding:NSUTF8StringEncoding];
+    NSData *sig = CFBridgingRelease(SecKeyCreateSignature((SecKeyRef)key, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (CFDataRef)data, (void *)&err));
+    ok(sig, "failed to create signature: %@", err);
+    ok(SecKeyVerifySignature((SecKeyRef)pubKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (CFDataRef)data, (CFDataRef)sig, (void *)&err), "failed to verify signature: %@", err);
+
+    status = SecItemDelete((CFDictionaryRef)query);
+    is(status, errSecSuccess, "deleting SEP key from keychain failed");
+
+    status = SecItemCopyMatching((CFDictionaryRef)query, (void *)&key);
+    is(status, errSecItemNotFound, "SEP key was not deleted from keychain");
+}
+
+static void secAccessControlDescriptionTest(void) {
+    NSError *error;
+    NSObject *ac = CFBridgingRelease(SecAccessControlCreate(kCFAllocatorDefault, (void *)&error));
+    ok(ac, "failed to create ac: %@", error);
+    ok(SecAccessControlSetProtection((__bridge SecAccessControlRef)ac, kSecAttrAccessibleWhenUnlocked, (void *)&error), "failed to set protection: %@", error);
+
+    NSString *desc = ac.description;
+    ok([desc isEqualToString:@"<SecAccessControlRef: ak>"], "unexpected desc: %@", desc);
+
+    SecAccessControlSetConstraints((__bridge SecAccessControlRef)ac, (__bridge CFDictionaryRef)@{});
+    desc = ac.description;
+    ok([desc isEqualToString:@"<SecAccessControlRef: ak>"], "unexpected desc: %@", desc);
+
+    SecAccessControlSetConstraints((__bridge SecAccessControlRef)ac, (__bridge CFDictionaryRef)@{@"od": (__bridge id)kCFBooleanTrue});
+    desc = ac.description;
+    ok([desc isEqualToString:@"<SecAccessControlRef: ak;od(true)>"], "unexpected desc: %@", desc);
+
+    SecAccessControlSetConstraints((__bridge SecAccessControlRef)ac, (__bridge CFDictionaryRef)@{@"od": (__bridge id)kCFBooleanTrue, @"oe": (__bridge id)kCFBooleanFalse});
+    desc = ac.description;
+    ok([desc isEqualToString:@"<SecAccessControlRef: ak;od(true);oe(false)>"], "unexpected desc: %@", desc);
+
+    SecAccessControlSetConstraints((__bridge SecAccessControlRef)ac, (__bridge CFDictionaryRef)@{@"od": @"huh"});
+    desc = ac.description;
+    ok([desc isEqualToString:@"<SecAccessControlRef: ak;od(huh)>"], "unexpected desc: %@", desc);
+
+    SecAccessControlSetConstraints((__bridge SecAccessControlRef)ac, (__bridge CFDictionaryRef)@{@"od": @2});
+    desc = ac.description;
+    ok([desc isEqualToString:@"<SecAccessControlRef: ak;od(2)>"], "unexpected desc: %@", desc);
+
+    NSData *shortData = [NSData dataWithBytes:"\x01\x02\x03" length:3];
+    SecAccessControlSetConstraints((__bridge SecAccessControlRef)ac, (__bridge CFDictionaryRef)@{@"od": shortData});
+    desc = ac.description;
+    ok([desc isEqualToString:@"<SecAccessControlRef: ak;od(010203)>"], "unexpected desc: %@", desc);
+
+    NSData *longData = [NSMutableData dataWithLength:128];
+    SecAccessControlSetConstraints((__bridge SecAccessControlRef)ac, (__bridge CFDictionaryRef)@{@"od": longData});
+    desc = ac.description;
+    ok([desc isEqualToString:@"<SecAccessControlRef: ak;od(00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...(128b))>"], "unexpected desc: %@", desc);
+
+    SecAccessControlSetConstraints((__bridge SecAccessControlRef)ac, (__bridge CFDictionaryRef)@{@"od": @{@"kofn": @2}});
+    desc = ac.description;
+    ok([desc isEqualToString:@"<SecAccessControlRef: ak;od(kofn(2))>"], "unexpected desc: %@", desc);
+}
+
 int si_44_seckey_aks(int argc, char *const *argv) {
     @autoreleasepool {
-        BOOL testPKA = YES;
-#if !TARGET_OS_OSX
-        NSNumber *hasPKA = (__bridge_transfer id)MGCopyAnswer(kMGQHasPKA, NULL);
-        if(![hasPKA isKindOfClass:NSNumber.class] || ![hasPKA boolValue]) {
-            testPKA = NO;
-        }
-#else
-        if (remote_device_copy_unique_of_type(REMOTE_DEVICE_TYPE_EOS) == nil && remote_device_copy_unique_of_type(REMOTE_DEVICE_TYPE_BRIDGE_COPROC) == nil) {
+        NSNumber *hasSEP = CFBridgingRelease(MGCopyAnswer(kMGQHasSEP, NULL));
+        if (!hasSEP.boolValue) {
             // macOS without SEP cannot run attestations at all.
             plan_tests(1);
             ok(true);
             return 0;
         }
 
-        testPKA = NO;
+        NSNumber *hasPKA = CFBridgingRelease(MGCopyAnswer(kMGQHasPKA, NULL));
+        plan_tests(hasPKA.boolValue ? 207 : 113);
+
+        secAccessControlDescriptionTest();
+        secKeySepTest(hasPKA.boolValue);
+
+        attestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, YES);
+        attestationTest(kSecAttrAccessibleUntilReboot, NO);
+
+        sysKeyAttestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, YES, "SysUIK", kSecKeyAttestationKeyTypeUIKCommitted, kSecKeyAttestationKeyTypeUIKProposed, YES);
+        sysKeyAttestationTest(kSecAttrAccessibleUntilReboot, NO, "SysUIK", kSecKeyAttestationKeyTypeUIKCommitted, kSecKeyAttestationKeyTypeUIKProposed, YES);
+
+        // OIK is too weird to be usable directly, just skip is testing for now.
+#if 0
+        sysKeyAttestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, YES, "OIK", kSecKeyAttestationKeyTypeOIKCommitted, kSecKeyAttestationKeyTypeOIKProposed, NO);
+        sysKeyAttestationTest(kSecAttrAccessibleUntilReboot, NO, "OIK", kSecKeyAttestationKeyTypeOIKCommitted, kSecKeyAttestationKeyTypeOIKProposed, NO);
 #endif
-        plan_tests(testPKA ? 100 : 85);
 
-        // Put SEP keys into test-keybag mode. Available only when running in direct-mode, not with extension.
-        SecKeySetParameter(NULL, kSecAttrTokenIDAppleKeyStore, kCFBooleanTrue, NULL);
-        rewrapTest();
-        SecKeySetParameter(NULL, kSecAttrTokenIDAppleKeyStore, kCFBooleanFalse, NULL);
+        sysKeyAttestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, YES, "DAK", kSecKeyAttestationKeyTypeDAKCommitted, kSecKeyAttestationKeyTypeDAKProposed, YES);
+        sysKeyAttestationTest(kSecAttrAccessibleUntilReboot, NO, "DAK", kSecKeyAttestationKeyTypeDAKCommitted, kSecKeyAttestationKeyTypeDAKProposed, YES);
+
+        keyFromBlobTest();
+        keychainTest();
+
+        if (hasPKA.boolValue) {
+            // Put SEP keys into test-keybag mode. Available only when running in direct-mode, not with extension.
+            SecKeySetParameter(NULL, kSecAttrTokenIDAppleKeyStore, kCFBooleanTrue, NULL);
+            rewrapTest();
+            SecKeySetParameter(NULL, kSecAttrTokenIDAppleKeyStore, kCFBooleanFalse, NULL);
+        }
 
-        secKeySepTest(testPKA);
-        attestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, NO);
-        attestationTest(kSecAttrAccessibleUntilReboot, YES);
         return 0;
     }
 }