Is there a certain way to detect if storing in Secure Enclave is available on current device?
-
As a last case solution, you could manually check the device model and compare it to a list of those you know have SEs – Alexander Jan 20 '17 at 09:22
-
and to do that you can check this answer http://stackoverflow.com/a/3950748/2246798 – souvickcse Jan 20 '17 at 10:09
-
I dont really like that way of checking and not what Im looking for. – kragekjaer Jan 20 '17 at 10:20
-
Ended up doing a mix: – kragekjaer Jan 25 '17 at 10:22
4 Answers
Here is another solution:
Device.h
#import <Foundation/Foundation.h>
@interface Device : NSObject
+(BOOL) hasSecureEnclave;
+(BOOL) isSimulator;
+(BOOL) hasBiometrics;
@end
Device.m
#import "Device.h"
#import <LocalAuthentication/LocalAuthentication.h>
@implementation Device
//To check that device has secure enclave or not
+(BOOL) hasSecureEnclave {
NSLog(@"IS Simulator : %d", [Device isSimulator]);
return [Device hasBiometrics] && ![Device isSimulator] ;
}
//To Check that this is this simulator
+(BOOL) isSimulator {
return TARGET_OS_SIMULATOR == 1;
}
//Check that this device has Biometrics features available
+(BOOL) hasBiometrics {
//Local Authentication Context
LAContext *localAuthContext = [[LAContext alloc] init];
NSError *error = nil;
/// Policies can have certain requirements which, when not satisfied, would always cause
/// the policy evaluation to fail - e.g. a passcode set, a fingerprint
/// enrolled with Touch ID or a face set up with Face ID. This method allows easy checking
/// for such conditions.
BOOL isValidPolicy = [localAuthContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];
if (isValidPolicy) {
if (@available(ios 11.0, *)){
if (error.code != kLAErrorBiometryNotAvailable){
isValidPolicy = true;
} else{
isValidPolicy = false;
}
}else{
if (error.code != kLAErrorTouchIDNotAvailable){
isValidPolicy = true;
}else{
isValidPolicy = false;
}
}
return isValidPolicy;
}
return isValidPolicy;
}
@end
If you want solution in Swift 4, then refer this link.

- 14,144
- 10
- 61
- 92
-
This check is not correct. What in case of iPad Air and iPad Mini 2 which have Secure Enclave but does not have Biometric authenticator? – Łukasz Łabuński Mar 25 '20 at 16:07
For a developer, there is exactly one thing the Secure Enclave can do: Create and hold private keys for elliptic curve cryptography, and encrypt or decrypt data using these keys. On iOS 9, the attributes describing elliptic curve algorithms are not there - therefore, if you are running iOS 9, then you can assume the Secure Enclave is not there, because you cannot use it.
On iOS 10 and above, there is just one way to decide guaranteed correctly if the Secure Enclave is present: Create an elliptic curve encryption key in the Secure Enclave, as described by Apple's documentation. If this fails, and the error has a code of -4 = errSecUnimplemented
, then there is no Secure Enclave.
If you insist on checking a list of devices, you only need the devices that are documented as having no Secure Enclave but are able to run iOS 10, because on iOS 9 it is never available.

- 8,770
- 2
- 50
- 71

- 51,477
- 5
- 75
- 98
-
4Hi, while generating EC key using `SecKeyCreateRandomKey` on a simulator, instead of getting an error code, the `SecKeyCreateRandomKey` crashes with EXC_BAD_ACCESS. Code runs fine on a real device that has secure enclave. Any ideas why this might be happening and how I can check for secure enclave instead? Thanks! – SeaJelly Oct 09 '19 at 05:08
I did it myself:
+ (BOOL) isDeviceOkForSecureEnclave
{
double OSVersionNumber = floor(NSFoundationVersionNumber);
UIUserInterfaceIdiom deviceType = [[UIDevice currentDevice] userInterfaceIdiom];
BOOL isOSForSecureEnclave = OSVersionNumber > NSFoundationVersionNumber_iOS_8_4 ? YES:NO;
//iOS 9 and up are ready for SE
BOOL isDeviceModelForSecureEnclave = NO;
switch (deviceType) {
case UIUserInterfaceIdiomPhone:
//iPhone
isDeviceModelForSecureEnclave = [self isPhoneForSE];
break;
case UIUserInterfaceIdiomPad:
//iPad
isDeviceModelForSecureEnclave = [self isPadForSE];
break;
default:
isDeviceModelForSecureEnclave = false;
break;
}
return (isOSForSecureEnclave && isDeviceModelForSecureEnclave) ? YES:NO;
}
/**
The arrays are models that we know not having SE in hardware, so if the current device is on the list it means it dosent have SE
*/
+ (BOOL) isPhoneForSE
{
NSString *thisPlatform = [self platform];
NSArray * oldModels = [NSArray arrayWithObjects:
@"x86_64",
@"iPhone1,1",
@"iPhone1,2",
@"iPhone2,1",
@"iPhone3,1",
@"iPhone3,3",
@"iPhone4,1",
@"iPhone5,1",
@"iPhone5,2",
@"iPhone5,3",
@"iPhone5,4", nil];
BOOL isInList = [oldModels containsObject: thisPlatform];
return !isInList;
}
+ (BOOL) isPadForSE
{
//iPad Mini 2 is the earliest with SE // "iPad4,4"
NSString *thisPlatform = [self platform];
NSArray * oldModels = [NSArray arrayWithObjects:
@"x86_64",
@"@iPad",
@"@iPad1,0",
@"@iPad1,1",
@"iPad2,1",
@"iPad2,2",
@"iPad2,3",
@"iPad2,4",
@"iPad2,5",
@"iPad2,6",
@"iPad2,7",
@"iPad3,1",
@"iPad3,2",
@"iPad3,3",
@"iPad3,4",
@"iPad3,5",
@"iPad3,6",nil];
BOOL isInList = [oldModels containsObject: thisPlatform];
return !isInList;
}
+ (NSString *)platform
{
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine = malloc(size);
sysctlbyname("hw.machine", machine, &size, NULL, 0);
NSString *platform = [NSString stringWithUTF8String:machine];
free(machine);
return platform;
}
@end

- 232
- 4
- 10
-
From what I can see the iPad Air (1st gen) and the iPad mini 2 does not have a secure enclave either. Therefore the iPad exclusion list needs to also include "iPad4,1", "iPad4,4", "iPad4,5", "iPad4,6". Plus remember not iPod touch have a secure enclave so you might also need another list… – wuf810 Sep 26 '17 at 14:42
-
Im not sure if I updated this code, if not hen some models are missing – kragekjaer Oct 03 '17 at 23:54
-
@wuf810 iPad Air (1st gen)s and the iPad mini 2 does have secure enclave. these devices use Apple's A7 processor which is stated to contain Secure Enclave. Anyways, tested and verified on both these devices – Mervyn Ong Dec 15 '17 at 06:52
There is a more straightforward way to check if Secure Enclave is available using the CryptoKit framework. The following approach is iOS 13+ and Swift only.
import CryptoKit
if TARGET_OS_SIMULATOR == 0 && SecureEnclave.isAvailable {
// use Secure Enclave
}
Additional check for Simulator is needed since SecureEnclave.isAvailable
returns true
running on a Simulator (checked on iOS 14.4).

- 135
- 3
- 11
-
Should have mentioned that this is iOS 13 only. And when it returns true on the simulator, have you checked if that is because it is running on a Mac with Secure Enclave? – gnasher729 Apr 15 '21 at 11:13
-
-
"The following approach is iOS 13+ and Swift only." and "Additional check for Simulator is needed since SecureEnclave.isAvailable returns true running on a Simulator (checked on iOS 14.4)." seems like clearly describing your concerns – podkovyr Apr 16 '21 at 12:33
-
1Adding for googleability: SecureEnclave does not work on the simulator. You might get "Error Domain=NSOSStatusErrorDomain Code=-25293 "Key generation failed, error -25293" UserInfo={numberOfErrorsDeep=0, NSDescription=Key generation failed, error -25293}" – Jonas357 Apr 24 '21 at 13:57