]> git.saurik.com Git - apple/security.git/blob - keychain/ckks/CKKS.h
Security-59754.41.1.tar.gz
[apple/security.git] / keychain / ckks / CKKS.h
1 /*
2 * Copyright (c) 2016 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 #ifndef CKKS_h
25 #define CKKS_h
26
27 #include <dispatch/dispatch.h>
28 #include "ipc/securityd_client.h"
29 #include "utilities/SecCFWrappers.h"
30 #include "utilities/SecDb.h"
31 #include <xpc/xpc.h>
32
33 #ifdef __OBJC__
34 #import <Foundation/Foundation.h>
35 #import "keychain/ot/OctagonStateMachine.h"
36 #endif /* __OBJC__ */
37
38 CF_ASSUME_NONNULL_BEGIN
39
40 #ifdef __OBJC__
41
42 typedef NS_ENUM(NSUInteger, SecCKKSItemEncryptionVersion) {
43 CKKSItemEncryptionVersionNone = 0, // No encryption present
44 CKKSItemEncryptionVersion1 = 1, // Current version, AES-SIV 512, not all fields authenticated
45 CKKSItemEncryptionVersion2 = 2, // Seed3 version, AES-SIV 512, all fields (including unknown fields) authenticated
46 };
47
48 extern const SecCKKSItemEncryptionVersion currentCKKSItemEncryptionVersion;
49
50 /* Queue Actions */
51 extern NSString* const SecCKKSActionAdd;
52 extern NSString* const SecCKKSActionDelete;
53 extern NSString* const SecCKKSActionModify;
54
55 /* Queue States */
56 @protocol SecCKKSItemState <NSObject>
57 @end
58 typedef NSString<SecCKKSItemState> CKKSItemState;
59 extern CKKSItemState* const SecCKKSStateNew;
60 extern CKKSItemState* const SecCKKSStateUnauthenticated;
61 extern CKKSItemState* const SecCKKSStateInFlight;
62 extern CKKSItemState* const SecCKKSStateReencrypt;
63 extern CKKSItemState* const SecCKKSStateError;
64 extern CKKSItemState* const SecCKKSStateDeleted; // meta-state: please delete this item!
65 extern CKKSItemState* const SecCKKSStateMismatchedView; // This item was for a different view at processing time. Held pending a policy refresh.
66
67 /* Processed States */
68 @protocol SecCKKSProcessedState <NSObject>
69 @end
70 typedef NSString<SecCKKSProcessedState> CKKSProcessedState;
71 extern CKKSProcessedState* const SecCKKSProcessedStateLocal;
72 extern CKKSProcessedState* const SecCKKSProcessedStateRemote;
73
74 /* Key Classes */
75 @protocol SecCKKSKeyClass <NSObject>
76 @end
77 typedef NSString<SecCKKSKeyClass> CKKSKeyClass;
78 extern CKKSKeyClass* const SecCKKSKeyClassTLK;
79 extern CKKSKeyClass* const SecCKKSKeyClassA;
80 extern CKKSKeyClass* const SecCKKSKeyClassC;
81
82 /* Useful CloudKit configuration */
83 extern NSString* SecCKKSContainerName;
84 extern bool SecCKKSContainerUsePCS;
85 extern NSString* const SecCKKSSubscriptionID;
86 extern NSString* const SecCKKSAPSNamedPort;
87
88 /* Item CKRecords */
89 extern NSString* const SecCKRecordItemType;
90 extern NSString* const SecCKRecordHostOSVersionKey;
91 extern NSString* const SecCKRecordEncryptionVersionKey;
92 extern NSString* const SecCKRecordParentKeyRefKey;
93 extern NSString* const SecCKRecordDataKey;
94 extern NSString* const SecCKRecordWrappedKeyKey;
95 extern NSString* const SecCKRecordGenerationCountKey;
96 extern NSString* const SecCKRecordPCSServiceIdentifier;
97 extern NSString* const SecCKRecordPCSPublicKey;
98 extern NSString* const SecCKRecordPCSPublicIdentity;
99 extern NSString* const SecCKRecordServerWasCurrent;
100
101 /* Intermediate Key CKRecord Keys */
102 extern NSString* const SecCKRecordIntermediateKeyType;
103 extern NSString* const SecCKRecordKeyClassKey;
104 //extern NSString* const SecCKRecordWrappedKeyKey;
105 //extern NSString* const SecCKRecordParentKeyRefKey;
106
107 /* TLK Share CKRecord Keys */
108 // These are a bit special; they can't use the record ID as information without parsing.
109 extern NSString* const SecCKRecordTLKShareType;
110 extern NSString* const SecCKRecordSenderPeerID;
111 extern NSString* const SecCKRecordReceiverPeerID;
112 extern NSString* const SecCKRecordReceiverPublicEncryptionKey;
113 extern NSString* const SecCKRecordCurve;
114 extern NSString* const SecCKRecordEpoch;
115 extern NSString* const SecCKRecordPoisoned;
116 extern NSString* const SecCKRecordSignature;
117 extern NSString* const SecCKRecordVersion;
118 //extern NSString* const SecCKRecordParentKeyRefKey; // reference to the key contained by this record
119 //extern NSString* const SecCKRecordWrappedKeyKey; // key material
120
121 /* Current Key CKRecord Keys */
122 extern NSString* const SecCKRecordCurrentKeyType;
123 // The key class will be the record name.
124 //extern NSString* const SecCKRecordParentKeyRefKey; <-- represent the current key for this key class
125
126 /* Current Item CKRecord Keys */
127 extern NSString* const SecCKRecordCurrentItemType;
128 extern NSString* const SecCKRecordItemRefKey;
129
130
131 /* Device State CKRecord Keys */
132 extern NSString* const SecCKRecordDeviceStateType;
133 extern NSString* const SecCKRecordCirclePeerID;
134 extern NSString* const SecCKRecordOctagonPeerID;
135 extern NSString* const SecCKRecordOctagonStatus;
136 extern NSString* const SecCKRecordCircleStatus;
137 extern NSString* const SecCKRecordKeyState;
138 extern NSString* const SecCKRecordCurrentTLK;
139 extern NSString* const SecCKRecordCurrentClassA;
140 extern NSString* const SecCKRecordCurrentClassC;
141 extern NSString* const SecCKSRecordLastUnlockTime;
142 extern NSString* const SecCKSRecordOSVersionKey; // Similar to SecCKRecordHostOSVersionKey, but better named
143
144 /* Manifest master CKRecord Keys */
145 extern NSString* const SecCKRecordManifestType;
146 extern NSString* const SecCKRecordManifestDigestValueKey;
147 extern NSString* const SecCKRecordManifestGenerationCountKey;
148 extern NSString* const SecCKRecordManifestLeafRecordIDsKey;
149 extern NSString* const SecCKRecordManifestPeerManifestRecordIDsKey;
150 extern NSString* const SecCKRecordManifestCurrentItemsKey;
151 extern NSString* const SecCKRecordManifestSignaturesKey;
152 extern NSString* const SecCKRecordManifestSignerIDKey;
153 extern NSString* const SecCKRecordManifestSchemaKey;
154
155 /* Manifest leaf CKRecord Keys */
156 extern NSString* const SecCKRecordManifestLeafType;
157 extern NSString* const SecCKRecordManifestLeafDERKey;
158 extern NSString* const SecCKRecordManifestLeafDigestKey;
159
160 /* Zone Key Hierarchy States */
161 #if OCTAGON
162 typedef OctagonState CKKSZoneKeyState;
163 #else
164 // This is here to allow for building with Octagon off
165 @protocol SecCKKSZoneKeyState <NSObject>
166 @end
167 typedef NSString<SecCKKSZoneKeyState> CKKSZoneKeyState;
168 #endif
169
170 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForCloudKitAccountStatus;
171
172 // CKKS is currently logged out
173 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateLoggedOut;
174
175 // Class has just been created.
176 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateInitializing;
177 // CKKSZone has just informed us that its setup is done (and completed successfully).
178 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateInitialized;
179 // CKKSZone has informed us that zone setup did not work. Try again soon!
180 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateZoneCreationFailed;
181
182 // Everything is likely ready. Double-check.
183 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateBecomeReady;
184 // Everything is ready and waiting for input.
185 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateReady;
186
187 // We're presumably ready, but we'd like to do one or two more checks after we unlock.
188 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateReadyPendingUnlock;
189
190 // A key hierarchy fetch will now begin
191 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateBeginFetch;
192
193 // We're currently refetching the zone
194 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateFetch;
195 // A Fetch has just been completed which includes some new keys to process
196 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateFetchComplete;
197 // We'd really like a full refetch.
198 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateNeedFullRefetch;
199
200 // The TLK doesn't appear to be present. Determine what to to next!
201 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateTLKMissing;
202
203 // We've received a wrapped TLK, but we don't have its contents yet. Wait until they arrive.
204 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTLK;
205
206 // No keys exist for this zone yet, and we're waiting to make some. Please call the "make TLKs" API.
207 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTLKCreation;
208 // No keys exist for this zone yet, but we've made some. Octagon should upload them.
209 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTLKUpload;
210
211 // We've received a wrapped TLK, but we can't process it until the keybag unlocks. Wait until then.
212 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForUnlock;
213 // Some operation has noticed that trust is lost. Will enter WaitForTrust.
214 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateLoseTrust;
215 // We've done some CK ops, but are waiting for the trust system to tell us to continue
216 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTrust;
217
218 // Things are unhealthy, but we're not sure entirely why.
219 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateUnhealthy;
220 // Something has gone horribly wrong with the current key pointers.
221 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateBadCurrentPointers;
222 // Something has gone wrong creating new TLKs.
223 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateNewTLKsFailed;
224 // Something isn't quite right with the TLK shares.
225 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKShares;
226 // Something has gone wrong fixing TLK shares.
227 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKSharesFailed;
228 // The key hierarchy state machine needs to wait for the fixup operation to complete
229 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForFixupOperation;
230 // The key hierarchy state machine is responding to a key state reprocess request
231 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateProcess;
232
233 // CKKS is resetting the remote zone, due to key hierarchy reasons. Will not proceed until the local reset occurs.
234 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingZone;
235 // CKKS is resetting the local data, likely to do a cloudkit reset or a rpc.
236 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingLocalData;
237
238 // Fatal error. Will not proceed unless fixed from outside class.
239 extern CKKSZoneKeyState* const SecCKKSZoneKeyStateError;
240
241 // If you absolutely need to numberify one of the above constants, here's your maps.
242 NSDictionary<CKKSZoneKeyState*, NSNumber*>* CKKSZoneKeyStateMap(void);
243 NSDictionary<NSNumber*, CKKSZoneKeyState*>* CKKSZoneKeyStateInverseMap(void);
244 NSNumber* CKKSZoneKeyToNumber(CKKSZoneKeyState* state);
245 CKKSZoneKeyState* CKKSZoneKeyRecover(NSNumber* stateNumber);
246
247 // Use this to determine if CKKS believes the current state is "transient": that is, should resolve itself with further local processing
248 // or 'nontransient': further local processing won't progress. Either we're ready, or waiting for the user to unlock, or a remote device to do something.
249 NSSet<CKKSZoneKeyState*>* CKKSKeyStateNonTransientStates(void);
250
251 /* Hide Item Length */
252 extern const NSUInteger SecCKKSItemPaddingBlockSize;
253
254 /* Aggd Keys */
255 extern NSString* const SecCKKSAggdPropagationDelay;
256 extern NSString* const SecCKKSAggdPrimaryKeyConflict;
257 extern NSString* const SecCKKSAggdViewKeyCount;
258 extern NSString* const SecCKKSAggdItemReencryption;
259
260 extern NSString* const SecCKKSUserDefaultsSuite;
261
262 extern NSString* const CKKSErrorDomain;
263 extern NSString* const CKKSServerExtensionErrorDomain;
264
265 /* Queue limits: these should likely be configurable via plist */
266 #define SecCKKSOutgoingQueueItemsAtOnce 100
267 #define SecCKKSIncomingQueueItemsAtOnce 50
268
269 // Utility functions
270 NSString* SecCKKSHostOSVersion(void);
271
272 #endif // OBJ-C
273
274 /* C functions to interact with CKKS */
275 void SecCKKSInitialize(SecDbRef db);
276 void SecCKKSNotifyBlock(SecDbConnectionRef dbconn, SecDbTransactionPhase phase, SecDbTransactionSource source, CFArrayRef changes);
277
278 // Called by XPC approximately every 3 days
279 void SecCKKS24hrNotification(void);
280
281 // Register this callback to receive a call when the item with this UUID next successfully (or unsuccessfully) exits the outgoing queue.
282 void CKKSRegisterSyncStatusCallback(CFStringRef cfuuid, SecBoolCFErrorCallback callback);
283
284 // Tells CKKS that the local keychain was reset, and that it should respond accordingly
285 void SecCKKSPerformLocalResync(void);
286
287 // Returns true if CloudKit keychain syncing should occur
288 bool SecCKKSIsEnabled(void);
289
290 bool SecCKKSEnable(void);
291 bool SecCKKSDisable(void);
292
293 bool SecCKKSResetSyncing(void);
294
295 bool SecCKKSSyncManifests(void);
296 bool SecCKKSEnableSyncManifests(void);
297 bool SecCKKSSetSyncManifests(bool value);
298
299 bool SecCKKSEnforceManifests(void);
300 bool SecCKKSEnableEnforceManifests(void);
301 bool SecCKKSSetEnforceManifests(bool value);
302
303 bool SecCKKSReduceRateLimiting(void);
304 bool SecCKKSSetReduceRateLimiting(bool value);
305
306 // Testing support
307 bool SecCKKSTestsEnabled(void);
308 bool SecCKKSTestsEnable(void);
309 bool SecCKKSTestsDisable(void);
310
311 void SecCKKSTestResetFlags(void);
312 bool SecCKKSTestDisableAutomaticUUID(void);
313 void SecCKKSTestSetDisableAutomaticUUID(bool set);
314
315 bool SecCKKSTestDisableSOS(void);
316 void SecCKKSTestSetDisableSOS(bool set);
317
318 bool SecCKKSTestDisableKeyNotifications(void);
319 void SecCKKSTestSetDisableKeyNotifications(bool set);
320
321 bool SecCKKSTestSkipScan(void);
322 bool SecCKKSSetTestSkipScan(bool value);
323
324 // TODO: handle errors better
325 typedef CF_ENUM(CFIndex, CKKSErrorCode) {
326 CKKSNotInitialized = 9,
327 CKKSNotLoggedIn = 10,
328 CKKSNoSuchView = 11,
329
330 CKKSRemoteItemChangePending = 12,
331 CKKSLocalItemChangePending = 13,
332 CKKSItemChanged = 14,
333 CKKSNoUUIDOnItem = 15,
334 CKKSItemCreationFailure = 16,
335 CKKSInvalidKeyClass = 17,
336 CKKSKeyNotSelfWrapped = 18,
337 CKKSNoTrustedPeer = 19,
338 CKKSDataMismatch = 20,
339 CKKSProtobufFailure = 21,
340 CKKSNoSuchRecord = 22,
341 CKKSMissingTLKShare = 23,
342 CKKSNoPeersAvailable = 24,
343
344 CKKSSplitKeyHierarchy = 32,
345 CKKSOrphanedKey = 33,
346 CKKSInvalidTLK = 34,
347 CKKSNoTrustedTLKShares = 35,
348 CKKSKeyUnknownFormat = 36,
349 CKKSNoSigningKey = 37,
350 CKKSNoEncryptionKey = 38,
351
352 CKKSNotHSA2 = 40,
353 CKKSiCloudGreyMode = 41,
354
355 CKKSNoFetchesRequested = 50,
356
357 CKKSNoMetric = 51,
358
359 CKKSLackingTrust = 52,
360 CKKSKeysMissing = 53,
361
362 CKKSCircularKeyReference = 54,
363
364 CKKSErrorViewIsPaused = 55,
365 CKKSErrorPolicyNotLoaded = 56,
366
367 CKKSErrorUnexpectedNil = 57,
368 };
369
370 typedef CF_ENUM(CFIndex, CKKSResultDescriptionErrorCode) {
371 CKKSResultDescriptionNone = 0,
372 CKKSResultDescriptionPendingKeyReady = 1,
373 CKKSResultDescriptionPendingSuccessfulFetch = 2,
374 CKKSResultDescriptionPendingAccountLoggedIn = 3,
375 CKKSResultDescriptionPendingUnlock = 4,
376 CKKSResultDescriptionPendingBottledPeerModifyRecords = 5,
377 CKKSResultDescriptionPendingBottledPeerFetchRecords = 6,
378
379 CKKSResultDescriptionPendingZoneChangeFetchScheduling = 1000,
380 CKKSResultDescriptionPendingViewChangedScheduling = 1001,
381 CKKSResultDescriptionPendingZoneInitializeScheduling = 1002, // No longer used
382 CKKSResultDescriptionPendingOutgoingQueueScheduling = 1003,
383 CKKSResultDescriptionPendingKeyHierachyPokeScheduling = 1004,
384 CKKSResultDescriptionPendingCloudKitRetryAfter = 1005,
385 CKKSResultDescriptionPendingFlag = 1006,
386 };
387
388 // These errors are returned by the CKKS server extension.
389 // Commented out codes here indicate that we don't currently handle them on the client side.
390 typedef CF_ENUM(CFIndex, CKKSServerExtensionErrorCode) {
391 // Generic Errors
392 //CKKSServerMissingField = 1,
393 CKKSServerMissingRecord = 2,
394 //CKKSServerUnexpectedFieldType = 3,
395 //CKKSServerUnexpectedRecordType = 4,
396 //CKKSServerUnepxectedRecordID = 5,
397
398 // Chain errors:
399 //CKKSServerMissingCurrentKeyPointer = 6,
400 //CKKSServerMissingCurrentKey = 7,
401 //CKKSServerUnexpectedSyncKeyClassInChain = 8,
402 CKKSServerUnexpectedSyncKeyInChain = 9,
403
404 // Item/Currentitem record errors:
405 //CKKSServerKeyrollingNotAllowed = 10,
406 //CKKSServerInvalidPublicIdentity = 11,
407 //CKKSServerPublicKeyMismatch = 12,
408 //CKKSServerServiceNumberMismatch = 13,
409 //CKKSServerUnknownServiceNumber = 14,
410 //CKKSServerEncverLessThanMinVal = 15,
411 //CKKSServerCannotModifyWasCurrent = 16,
412 //CKKSServerInvalidCurrentItem = 17,
413 };
414
415 #if __OBJC__
416
417 #define SecTranslateError(nserrorptr, cferror) \
418 if(nserrorptr) { \
419 *nserrorptr = (__bridge_transfer NSError*)cferror; \
420 } else { \
421 CFReleaseNull(cferror); \
422 }
423
424 extern os_log_t CKKSLogObject(NSString* scope, NSString* _Nullable zoneName);
425
426 // Very similar to the secerror, secnotice, and secinfo macros in debugging.h, but add zoneNames
427 #define ckkserrorwithzonename(scope, zoneName, format, ...) \
428 { \
429 os_log_with_type(CKKSLogObject(@scope, zoneName), \
430 OS_LOG_TYPE_ERROR, \
431 format, \
432 ##__VA_ARGS__); \
433 }
434
435 #define ckkserror(scope, zoneNameBearer, format, ...) \
436 ckkserrorwithzonename(scope, zoneNameBearer.zoneName, format, ##__VA_ARGS__)
437
438 #define ckkserror_global(scope, format, ...) \
439 ckkserrorwithzonename(scope, nil, format, ##__VA_ARGS__)
440
441 #define ckksnotice(scope, zoneNameBearer, format, ...) \
442 os_log(CKKSLogObject(@scope, zoneNameBearer.zoneName), format, ##__VA_ARGS__)
443
444 #define ckksnotice_global(scope, format, ...) \
445 os_log(CKKSLogObject(@scope, nil), format, ##__VA_ARGS__)
446
447 #define ckksinfo(scope, zoneNameBearer, format, ...) \
448 os_log_debug(CKKSLogObject(@scope, zoneNameBearer.zoneName), format, ##__VA_ARGS__)
449
450 #define ckksinfo_global(scope, format, ...) \
451 os_log_debug(CKKSLogObject(@scope, nil), format, ##__VA_ARGS__)
452
453 #endif // __OBJC__
454
455 CF_ASSUME_NONNULL_END
456
457 #endif /* CKKS_h */
458