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