]> git.saurik.com Git - apple/security.git/blob - OSX/shared_regressions/si-44-seckey-aks.m
Security-58286.230.21.tar.gz
[apple/security.git] / OSX / shared_regressions / si-44-seckey-aks.m
1 //
2 // Copyright 2016 Apple. All rights reserved.
3 //
4
5 #import <Foundation/Foundation.h>
6 #import <Security/Security.h>
7 #import <Security/SecItemPriv.h>
8 #import <Security/SecKeyPriv.h>
9 #if !TARGET_OS_OSX
10 #import "MobileGestalt.h"
11 #else
12 #import <RemoteServiceDiscovery/RemoteServiceDiscovery.h>
13 #endif
14
15 #import "shared_regressions.h"
16
17 static id generateKey(id keyType, CFStringRef protection) {
18 id accessControl = (__bridge_transfer id)SecAccessControlCreateWithFlags(NULL, protection, kSecAccessControlPrivateKeyUsage, NULL);
19 NSDictionary *keyAttributes = @{ (id)kSecAttrTokenID : (id)kSecAttrTokenIDAppleKeyStore,
20 (id)kSecAttrKeyType : keyType,
21 (id)kSecAttrAccessControl : accessControl,
22 (id)kSecAttrIsPermanent : @NO };
23 NSError *error;
24 id key = (__bridge_transfer id)SecKeyCreateRandomKey((CFDictionaryRef)keyAttributes, (void *)&error);
25 ok(key, "failed to create random key %@", error);
26 return key;
27 }
28
29 static void secKeySepTest(BOOL testPKA) {
30 NSArray *keyTypes;
31 if (testPKA) {
32 keyTypes = @[(id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeyTypeECSECPrimeRandomPKA, (id)kSecAttrKeyTypeSecureEnclaveAttestation];
33 } else {
34 keyTypes = @[(id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeyTypeSecureEnclaveAttestation];
35 }
36 for (id keyType in keyTypes) {
37 id privateKey = generateKey((id)keyType, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly);
38 ok(privateKey, "failed to create key '%@'", keyType);
39 id publicKey = (__bridge_transfer id)SecKeyCopyPublicKey((SecKeyRef)privateKey);
40
41 NSArray *attestaionKeyTypes = @[@(kSecKeyAttestationKeyTypeSIK), @(kSecKeyAttestationKeyTypeGID)];
42 for (NSNumber *attestationKeyType in attestaionKeyTypes) {
43 id attestationKey = (__bridge_transfer id)SecKeyCopyAttestationKey([attestationKeyType unsignedIntValue], NULL);
44 ok(attestationKey, "failed to create attestaion key '%@'", attestationKeyType);
45 NSError *error;
46 if (![keyType isEqual:(id)kSecAttrKeyTypeSecureEnclaveAttestation]) {
47 const char rawData[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
48 NSData *dataToSign = [NSData dataWithBytes:rawData length:sizeof(rawData)];
49 NSData *signedData = (__bridge_transfer NSData*)SecKeyCreateSignature((SecKeyRef)privateKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (__bridge CFDataRef)dataToSign, (void *)&error);
50 ok(signedData, "failed to sign data, error %@", error);
51 error = nil;
52 ok(SecKeyVerifySignature((SecKeyRef)publicKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (__bridge CFDataRef)dataToSign, (__bridge CFDataRef)signedData, (void *)&error),
53 "failed to verify data '%@'", error);
54
55 // Try signing large data.
56 dataToSign = [NSMutableData dataWithLength:10 * 1024 * 1024];
57 error = nil;
58 signedData = (__bridge_transfer NSData*)SecKeyCreateSignature((SecKeyRef)privateKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (__bridge CFDataRef)dataToSign, (void *)&error);
59 ok(signedData, "failed to sign data, error %@", error);
60 error = nil;
61 ok(SecKeyVerifySignature((SecKeyRef)publicKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (__bridge CFDataRef)dataToSign, (__bridge CFDataRef)signedData, (void *)&error),
62 "failed to verify data '%@'", error);
63 }
64 NSData *attestationData = (__bridge_transfer NSData *)SecKeyCreateAttestation((__bridge SecKeyRef)attestationKey, (__bridge SecKeyRef)privateKey, (void *)&error);
65 ok(attestationData, "failed to attest key '%@'", error);
66 }
67
68 NSDictionary *keyAttrs = (__bridge_transfer NSDictionary *)SecKeyCopyAttributes((SecKeyRef)privateKey);
69 NSData *keyBlob = keyAttrs[(id)kSecAttrTokenOID];
70
71 NSDictionary *params = @{ (id)kSecAttrTokenID : (id)kSecAttrTokenIDAppleKeyStore,
72 (id)kSecAttrTokenOID : keyBlob,
73 (id)kSecReturnRef : @YES };
74
75 privateKey = nil;
76 NSError *error;
77 privateKey = (__bridge_transfer id)SecKeyCreateWithData((__bridge CFDataRef)keyBlob, (__bridge CFDictionaryRef)params, (void *)&error);
78 ok(privateKey, "failed to create key with data '%@'", error);
79 // <rdar://problem/30651629> SecItemAdd fails to create SecKey from aks key blob
80 //
81 // ok_status(SecItemAdd((__bridge CFDictionaryRef)params, (void *)&privateKey), "failed to create key from aks blob");
82 // ok_status(SecItemDelete((__bridge CFDictionaryRef) @{(id)kSecValueRef : privateKey}), "failed to delete key from aks blob");
83 }
84 }
85
86 static void attestationTest(CFStringRef protection) {
87 NSError *error;
88 id privKey = generateKey((id)kSecAttrKeyTypeECSECPrimeRandom, protection);
89 id uik = generateKey((id)kSecAttrKeyTypeSecureEnclaveAttestation, protection);
90 id sik = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeSIK, (void *)&error));
91 ok(sik != nil, "get SIK key: %@", error);
92
93 id pubSIK = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sik));
94 ok(pubSIK != nil, "get SIK pubkey");
95
96 error = nil;
97 NSData *attSIKPlain = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)uik, (void *)&error));
98 ok(attSIKPlain != nil, "SIK attesting UIK, no nonce: %@", error);
99
100 error = nil;
101 NSData *attUIKPlain = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)uik, (__bridge SecKeyRef)privKey, (void *)&error));
102 ok(attUIKPlain != nil, "UIK attesting privKey, no nonce: %@", error);
103
104 error = nil;
105 NSData *nonce = [@"TESTnonce" dataUsingEncoding:NSUTF8StringEncoding];
106 ok(SecKeySetParameter((__bridge SecKeyRef)sik, kSecKeyParameterSETokenAttestationNonce, (__bridge CFPropertyListRef)nonce, (void *)&error), "Set nonce to SIK: %@", error);
107 NSData *attSIKNonce = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)uik, (void *)&error));
108 ok(attSIKNonce != nil, "SIK attesting UIK, with nonce: %@", error);
109
110 error = nil;
111 ok(SecKeySetParameter((__bridge SecKeyRef)uik, kSecKeyParameterSETokenAttestationNonce, (__bridge CFPropertyListRef)nonce, (void *)&error), "Set nonce to UIK: %@", error);
112 NSData *attUIKNonce = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)uik, (__bridge SecKeyRef)privKey, (void *)&error));
113 ok(attUIKNonce != nil, "SIK attesting UIK, with nonce: %@", error);
114
115 error = nil;
116 id sysUikC = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeUIKCommitted, (void *)&error));
117 if (sysUikC == nil) {
118 // Platform does not support system UIK, so just fake test rounds to avoid testplan counting failures.
119 for (int i = 0; i < 19; i++) {
120 ok(true);
121 }
122 } else {
123 ok(sysUikC != nil, "get UIK-committed key, error: %@", error);
124 error = nil;
125 id sysUikP = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeUIKProposed, (void *)&error));
126 ok(sysUikP != nil, "get UIK-proposed key: %@", error);
127
128 error = nil;
129 NSData *attUIKC = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error));
130 ok(attUIKC != nil, "Sys-UIK-committed attesting privKey: %@", error);
131
132 error = nil;
133 NSData *attUIKP = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error));
134 ok(attUIKP != nil, "Sys-UIK-proposed attesting privKey: %@", error);
135
136 id pubUIKP = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikP));
137 ok(pubUIKP != nil, "Sys-UIK-proposed copy public key");
138 id pubUIKC = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikC));
139 ok(pubUIKC != nil, "Sys-UIK-proposed copy public key");
140 ok([pubUIKP isEqual:pubUIKC], "Sys-UIK proposed and committed are same before bump");
141
142 BOOL res = SecKeyControlLifetime((__bridge SecKeyRef)sysUikC, kSecKeyControlLifetimeTypeBump, (void *)&error);
143 ok(res, "bumping sys-uik: %@", error);
144
145 error = nil;
146 NSData *attUIKCN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error));
147 ok(attUIKCN != nil, "Sys-UIK-committed attesting privKey: %@", error);
148
149 error = nil;
150 NSData *attUIKPN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error));
151 ok(attUIKPN != nil, "Sys-UIK-proposed attesting privKey: %@", error);
152
153 id pubUIKPN = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikP));
154 ok(pubUIKPN != nil, "Sys-UIK-proposed copy public key");
155 ok(![pubUIKPN isEqual:pubUIKC], "Sys-UIK proposed and committed differ after bump");
156
157 res = SecKeyControlLifetime((__bridge SecKeyRef)sysUikP, kSecKeyControlLifetimeTypeCommit, (void *)&error);
158 ok(res, "committing sys-uik: %@", error);
159
160 error = nil;
161 NSData *attUIKCNN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikC, (__bridge SecKeyRef)privKey, (void *)&error));
162 ok(attUIKCNN != nil, "Sys-UIK-committed attesting privKey: %@", error);
163
164 error = nil;
165 NSData *attUIKPNN = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sysUikP, (__bridge SecKeyRef)privKey, (void *)&error));
166 ok(attUIKPNN != nil, "Sys-UIK-proposed attesting privKey: %@", error);
167
168 id pubUIKCN = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)sysUikC));
169 ok(pubUIKCN != nil, "Sys-UIK-committed copy public key");
170 ok([pubUIKPN isEqual:pubUIKC], "Sys-UIK proposed and committed same after commit");
171
172 // Attest system-UIK with SIK
173 NSData *attSIKUIKP = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)sysUikP, (void *)&error));
174 ok(attSIKUIKP != nil, "SIK attesting Sys-UIK-proposed, error: %@", error);
175
176 NSData *attSIKUIKC = CFBridgingRelease(SecKeyCreateAttestation((__bridge SecKeyRef)sik, (__bridge SecKeyRef)sysUikC, (void *)&error));
177 ok(attSIKUIKC != nil, "SIK attesting Sys-UIK-committed, error: %@", error);
178 }
179 }
180
181 int si_44_seckey_aks(int argc, char *const *argv) {
182 @autoreleasepool {
183 BOOL testPKA = YES;
184 #if !TARGET_OS_OSX
185 NSNumber *hasPKA = (__bridge_transfer id)MGCopyAnswer(kMGQHasPKA, NULL);
186 if(![hasPKA isKindOfClass:NSNumber.class] || ![hasPKA boolValue]) {
187 testPKA = NO;
188 }
189 #else
190 if (remote_device_copy_unique_of_type(REMOTE_DEVICE_TYPE_EOS) == nil && remote_device_copy_unique_of_type(REMOTE_DEVICE_TYPE_BRIDGE_COPROC) == nil) {
191 // macOS without SEP cannot run attestations at all.
192 plan_tests(1);
193 ok(true);
194 return 0;
195 }
196
197 testPKA = NO;
198 #endif
199 plan_tests(testPKA ? 95 : 80);
200 secKeySepTest(testPKA);
201 attestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly);
202 attestationTest(kSecAttrAccessibleUntilReboot);
203 return 0;
204 }
205 }