/ keychain / ckks / CKKSKeychainBackedKey.h
CKKSKeychainBackedKey.h
  1  /*
  2   * Copyright (c) 2018 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  #if OCTAGON
 25  
 26  #import <Foundation/Foundation.h>
 27  
 28  #import "keychain/ckks/CKKS.h"
 29  #import "keychain/ckks/CKKSRecordHolder.h"
 30  #import "keychain/ckks/CKKSSIV.h"
 31  #import "keychain/ckks/proto/generated_source/CKKSSerializedKey.h"
 32  
 33  NS_ASSUME_NONNULL_BEGIN
 34  
 35  // Important note: while this class does conform to NSSecureCoding,
 36  // for safety reasons encoding a CKKSKeychainBackedKey will ~not~
 37  // encode the aessivkey. If you want your receiver to have access
 38  // to the original key material, they must successfully call
 39  // loadKeyMaterialFromKeychain.
 40  
 41  @interface CKKSKeychainBackedKey : NSObject <NSCopying, NSSecureCoding>
 42  @property NSString* uuid;
 43  @property NSString* parentKeyUUID;
 44  @property CKKSKeyClass* keyclass;
 45  @property CKRecordZoneID* zoneID;
 46  
 47  // Actual key material
 48  @property CKKSWrappedAESSIVKey* wrappedkey;
 49  @property (nullable) CKKSAESSIVKey* aessivkey;
 50  
 51  - (instancetype)init NS_UNAVAILABLE;
 52  - (instancetype _Nullable)initSelfWrappedWithAESKey:(CKKSAESSIVKey*)aeskey
 53                                                 uuid:(NSString*)uuid
 54                                             keyclass:(CKKSKeyClass*)keyclass
 55                                               zoneID:(CKRecordZoneID*)zoneID;
 56  
 57  - (instancetype _Nullable)initWrappedBy:(CKKSKeychainBackedKey*)wrappingKey
 58                                   AESKey:(CKKSAESSIVKey*)aessivkey
 59                                     uuid:(NSString*)uuid
 60                                 keyclass:(CKKSKeyClass*)keyclass
 61                                   zoneID:(CKRecordZoneID*)zoneID;
 62  
 63  - (instancetype)initWithWrappedAESKey:(CKKSWrappedAESSIVKey* _Nullable)wrappedaeskey
 64                                   uuid:(NSString*)uuid
 65                          parentKeyUUID:(NSString*)parentKeyUUID
 66                               keyclass:(CKKSKeyClass*)keyclass
 67                                 zoneID:(CKRecordZoneID*)zoneID;
 68  
 69  // Creates new random keys, in the parent's zone
 70  + (instancetype _Nullable)randomKeyWrappedByParent:(CKKSKeychainBackedKey*)parentKey
 71                                               error:(NSError* __autoreleasing*)error;
 72  
 73  + (instancetype _Nullable)randomKeyWrappedByParent:(CKKSKeychainBackedKey*)parentKey
 74                                            keyclass:(CKKSKeyClass*)keyclass
 75                                               error:(NSError* __autoreleasing*)error;
 76  
 77  // Creates a new random key that wraps itself
 78  + (instancetype _Nullable)randomKeyWrappedBySelf:(CKRecordZoneID*)zoneID
 79                                             error:(NSError* __autoreleasing*)error;
 80  
 81  /* Helper functions for persisting key material in the keychain */
 82  - (BOOL)saveKeyMaterialToKeychain:(NSError* __autoreleasing*)error;
 83  - (BOOL)saveKeyMaterialToKeychain:(bool)stashTLK
 84                              error:(NSError* __autoreleasing*)error;  // call this to not stash a non-syncable TLK, if that's what you want
 85  
 86  - (BOOL)loadKeyMaterialFromKeychain:(NSError* __autoreleasing*)error;
 87  - (BOOL)deleteKeyMaterialFromKeychain:(NSError* __autoreleasing*)error;
 88  
 89  // Class methods to help tests
 90  + (NSDictionary* _Nullable)setKeyMaterialInKeychain:(NSDictionary*)query
 91                                                error:(NSError* __autoreleasing*)error;
 92  
 93  + (NSDictionary* _Nullable)queryKeyMaterialInKeychain:(NSDictionary*)query
 94                                                  error:(NSError* __autoreleasing*)error;
 95  
 96  + (instancetype _Nullable)keyFromKeychain:(NSString*)uuid
 97                              parentKeyUUID:(NSString*)parentKeyUUID
 98                                   keyclass:(CKKSKeyClass*)keyclass
 99                                     zoneID:(CKRecordZoneID*)zoneID
100                                      error:(NSError* __autoreleasing*)error;
101  
102  /* Returns true if we believe this key wraps itself. */
103  - (bool)wrapsSelf;
104  
105  // Attempts checks if the AES key is already loaded, or attempts to load it from the keychain. Returns nil if it fails.
106  - (CKKSAESSIVKey* _Nullable)ensureKeyLoaded:(NSError* __autoreleasing*)error;
107  
108  // On a self-wrapped key, determine if this AES-SIV key is the self-wrapped key.
109  // If it is, save the key as this CKKSKey's unwrapped key.
110  - (bool)trySelfWrappedKeyCandidate:(CKKSAESSIVKey*)candidate
111                               error:(NSError* __autoreleasing*)error;
112  
113  - (CKKSWrappedAESSIVKey* _Nullable)wrapAESKey:(CKKSAESSIVKey*)keyToWrap
114                                          error:(NSError* __autoreleasing*)error;
115  
116  - (CKKSAESSIVKey* _Nullable)unwrapAESKey:(CKKSWrappedAESSIVKey*)keyToUnwrap
117                                     error:(NSError* __autoreleasing*)error;
118  
119  - (bool)wrapUnder:(CKKSKeychainBackedKey*)wrappingKey
120              error:(NSError* __autoreleasing*)error;
121  
122  - (bool)unwrapSelfWithAESKey:(CKKSAESSIVKey*)unwrappingKey
123                         error:(NSError* __autoreleasing*)error;
124  
125  - (NSData* _Nullable)encryptData:(NSData*)plaintext
126                 authenticatedData:(NSDictionary<NSString*, NSData*>* _Nullable)ad
127                             error:(NSError* __autoreleasing*)error;
128  
129  - (NSData* _Nullable)decryptData:(NSData*)ciphertext
130                 authenticatedData:(NSDictionary<NSString*, NSData*>* _Nullable)ad
131                             error:(NSError* __autoreleasing*)error;
132  
133  - (NSData* _Nullable)serializeAsProtobuf:(NSError* __autoreleasing*)error;
134  
135  + (CKKSKeychainBackedKey* _Nullable)loadFromProtobuf:(NSData*)data
136                                                 error:(NSError* __autoreleasing*)error;
137  @end
138  
139  // Useful when sending keys across interface boundaries
140  @interface CKKSKeychainBackedKeySet : NSObject <NSSecureCoding>
141  @property CKKSKeychainBackedKey* tlk;
142  @property CKKSKeychainBackedKey* classA;
143  @property CKKSKeychainBackedKey* classC;
144  @property BOOL newUpload;
145  
146  - (instancetype)initWithTLK:(CKKSKeychainBackedKey*)tlk
147                       classA:(CKKSKeychainBackedKey*)classA
148                       classC:(CKKSKeychainBackedKey*)classC
149                    newUpload:(BOOL)newUpload;
150  @end
151  
152  
153  NS_ASSUME_NONNULL_END
154  
155  #endif