The iPhone Wiki is no longer updated. Visit this article on The Apple Wiki for current information. |
Touch ID
The iPhone 5S comes equipped with a fingerprint scanner. There is not an official developer API for it.
However there is a private API for it. The dylib file for it is here: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/PrivateFrameworks/BiometricKit.framework/BiometricKit
It contains only a 64-bit Arm segment, and so the common disassembly tools cannot process the instructions well.
Inferred Information
Based on the string dump, here is what is implied.
- The codename for it was "mesa"
- It communicates over XPC to a binary that handles access to it
- There's a kernel extension to interface with it
- The kernel extension communicates to the secure keystore to set and verify fingerprints
- The fingerprint scanner calibrates itself and has upgradable firmware
- The fingerprint scanner uses normal image formats (i.e. UIImage) before setting and verifying fingerprints
- There's biometric lockout as well as passcode lockout
String Dump
Here is the long string dump of the contents of the BiometricKit library. These strings hint at the functionality of the framework.
initWithMachServiceName:options: connectWithReplyBlock: registerDelegate:withReplyBlock: suspendWork:withReplyBlock: enroll:withAuthToken:withReplyBlock: match:withReplyBlock: match:withOptions:withReplyBlock: matchIdentities:withReplyBlock: cancelWithReplyBlock: updateIdentity:withReplyBlock: removeIdentity:withReplyBlock: getIdentityFromUUID:withReplyBlock: identities:withReplyBlock: resetEngineWithReplyBlock: registerDSID:withAuthToken:withReplyBlock: registerStoreToken:withReplyBlock: getCountersignedStoreTokenWithReplyBlock: getMaxIdentityCount:withReplyBlock: enrollContinueWithReplyBlock: pullAlignmentDataWithReplyBlock: pullMatchTopologyDataWithReplyBlock: getNodeTopologyForIdentity:withReplyBlock: preventAutonomousMatchingMode:withReplyBlock: getProvisioningStateWithReplyBlock: getCalBlobVersionWithReplyBlock: getSensorCalibrationStatusWithReplyBlock: getCalibrationDataStateWithReplyBlock: setDebugImages:withReplyBlock: pullCaptureBufferWithReplyBlock: pullDebugImageData:withReplyBlock: provisionSensorWithReplyBlock: unpairSensorWithReplyBlock: lockSensorWithReplyBlock: getSerialisedTemplateForIdentity:withReplyBlock: interfaceWithProtocol: setRemoteObjectInterface: remoteObjectInterface setWithObject: setClasses:forSelector:argumentIndex:ofReply: setWithObjects: enrollResult: matchResult: statusMessage: homeButtonPressed setExportedInterface: setExportedObject: setInterruptionHandler: resume invalidate remoteObjectProxyWithErrorHandler: code respondsToSelector: connect registerDelegate: suspendWork: enroll:withAuthToken: match: match:withOptions: matchIdentities: cancel updateIdentity: removeIdentity: getIdentityFromUUID: identities: getMaxIdentityCount: resetEngine enrollContinue pullAlignmentData pullMatchTopologyData getNodeTopologyForIdentity: preventAutonomousMatchingMode: getProvisioningState registerDSID:withAuthToken: registerStoreToken: getCountersignedStoreToken: getCalBlobVersion getSensorCalibrationStatus getCalibrationDataState pullCaptureBuffer pullDebugImageData:imageWidth:imageHeight: provisionSensor unpairSensor lockSensor setDebugImages: getSerialisedTemplateForIdentity: delegate setDelegate: interruptionHandler _connection _delegate _interruptionHandler setTopology: setDetails: topology details _topology _details initEnrollmentValues message messageDetails objectForKeyedSubscript: currentPrimaryComponentID integerValue doubleValue statistics enroll: enrollResult:componentSet: enrollProgress: _fingerOn _enrolling _badImagePerFingerDown _enrollmentStarTime _touchesPerEnroll _badImagesPerEnroll _rejectedImagesPerEnroll _primaryClusterAdditions _primaryClusterFailedAdditions _otherClustersAdditions _joinEvents _area _primaryClusterArea numberWithBool: preferencesGetStringValue: preferencesGetBOOLValue: enableLogger:toPath: manager defaultCenter appDidEnterBackground: addObserver:selector:name:object: appWillEnterForeground: bundleForClass: imageNamed:inBundle: updateEnableLogger dataWithBytes:length: startEnrollLog data logRemoveIdentity: bytes imageFromRawImageData: imageFromBitmapData:inRect: pullDebugImageData:target: getRadarAtachmentsForLastEnrollment getRadarAtachmentsForLastMatch length stringWithString: getModulationRatio stringForProvisioningState: getSensorPatchVersion stringWithFormat: getLogsForProcess: sharedConnection isFingerprintUnlockAllowed setGracePeriod:passcode:completionBlock: finishEnrollLogWithStatus:withIdentity:withTemplate: matchResult:withDetails: createMatchInfo:withTopology:withMatchImage: logMatchResult:withTopology:withImage:withCaptureBuffer:withTemplate: getBytes:length: logEnrollMessage:withTopology:withImage:withCaptureBuffer: logStatus: enrollProgressMessage: logRejectedImage: size drawInRect: drawInRect:blendMode:alpha: CGImage scale imageOrientation imageWithCGImage:scale:orientation: imageWithImage:inRect: identityImage: imageWithImage:withNode:withRect:alpha: compositeTopologyImage: imageTopology:forGroup: imageFauxprint:withTheta:withLamda: greenColor imageWithImage:withTintColor: dataWithData: imageWithCGImage: preferencesSetBOOLValue:forKey: pullDebugImage: getLoggerAttachmentsForRadar: stringFromSensorConfiguration matchIdentity: topologyImage: imageWithImage:withMaskImage: inUse setInUse: enrollProgressConfigRenderMode setEnrollProgressConfigRenderMode: enrollProgressConfigRenderViewSize setEnrollProgressConfigRenderViewSize: renderMode setRenderMode: opacity setOpacity: _xpcClient _enrollingMode _matchingMode _statistics _scanbedImage _fauxprintImage _nodeRect _images _compSet _rejectTouchCount _rejectTouch _showDebugImages _enableLogger _enrollImageSet _isInternalInstall _inUse _enrollProgressConfigRenderMode _renderMode _opacity _enrollProgressConfigRenderViewSize setUuid: decodeBytesForKey:returnedLength: initWithUUIDBytes: decodeIntForKey: decodeObjectOfClass:forKey: copy getUUIDBytes: encodeBytes:length:forKey: encodeInt:forKey: encodeObject:forKey: biometricKitIdentity supportsSecureCoding encodeWithCoder: initWithCoder: uuid type setType: attribute setAttribute: entity setEntity: name setName: stringByReplacingOccurrencesOfString:withString: initWithCapacity: setLength: mutableBytes defaultManager createDirectoryAtPath:withIntermediateDirectories:attributes:error: removeItemAtPath:error: UUIDString setMessageDetails: setCaptureImage: setRenderedImage: progress setProgress: setCurrentPrimaryComponentID: captureImage renderedImage setMessage: _message _progress _currentPrimaryComponentID _captureImage _renderedImage _messageDetails setX: setY: angle setAngle: _angle setTransformationCoordinates: componentID setComponentID: transformationCoordinates _componentID _transformationCoordinates pathComponents com.apple.biometrickitd T@"<BiometricKitDelegate>",N,V_delegate interruptionHandler T@?,C,N,V_interruptionHandler topology T@"NSDictionary",&,N,V_details com.apple.fingerprint.enroll.attempts com.apple.fingerprint.enroll.passes com.apple.fingerprint.enroll.touchesPerEnroll com.apple.fingerprint.enroll.badImagesPerEnroll com.apple.fingerprint.enroll.rejectedImagesPerEnroll com.apple.fingerprint.enroll.primaryClusterAdditions com.apple.fingerprint.enroll.primaryClusterFailedAdditions com.apple.fingerprint.enroll.otherClustersAdditions com.apple.fingerprint.enroll.joinEvents com.apple.fingerprint.enroll.clusterCount com.apple.fingerprint.enroll.nodeCount com.apple.fingerprint.enroll.primaryClusterNodeCount com.apple.fingerprint.enroll.area com.apple.fingerprint.enroll.primaryClusterArea com.apple.fingerprint.enroll.passTime com.apple.fingerprint.enroll.fails com.apple.fingerprint.enroll.failTime com.apple.ManagedConfiguration.profileListChanged com.apple.biometrickitd.debugLogEnabled com.apple.biometrickitd.debugLogPath debugLogEnabled debugLogPath BKOptionSuppressHapticFeedback BKOptionFilterOutHomeButtonEvents BKOptionMatchForUnlock InternalBuild scanbed synthetic Uninitialized Not Provisioned Unprovisioned Provisioned Provisioned Locked Unpaired Unknown biosensor,mesa modulation-ratio AppleBiometricSensor patch-version Mesa configuration: Provisioning Status: %@ Calibrated: - Version: - Signed: Modulation ratio: Kernel: Thick kernel Thin kernel Sensor Patch Version: Steps to Reproduce: inUse TB,V_inUse enrollProgressConfigRenderMode Ti,N,V_enrollProgressConfigRenderMode enrollProgressConfigRenderViewSize T{CGSize=dd},N,V_enrollProgressConfigRenderViewSize renderMode Ti,N,V_renderMode opacity Tf,N,V_opacity Notification callback. BiometricKitErrorDomain BKIdentityUUID BKIdentityType BKIdentityAttribute BKIdentityEntityNumber BKIdentityName /var/mobile/BiometricKit/biometrickitd BKEPDReason BKEPDNewNodeID BKEPDNewComponentID BKEPDNewNodeCoordinates BKEPDRemovedNodeID BKEPDRemovedComponentID BKEPDExtendedComponentID BKEPDResultComponentID BKEPDMergedInComponents BKEPDRedundantNode BKTDLargestCompArea BKTDLargestCompNodes BKTDTotalArea BKTDTotalNodes BKTemplateUpdated Td,N,V_x Td,N,V_y angle Td,N,V_angle componentID Tq,N,V_componentID transformationCoordinates T@"BiometricKitEnrollProgressCoordinates",&,N,V_transformationCoordinates Remove identity: %@ Log package:%@ biometrickitd %@.tar.gz cd %@ && tar -cjf %@ %@ Time: % 8.3f PASS FAIL Closing log with result %@ Template identity: UUID : %@ Type : %i Attrib: %i Entity: %i Error: Unable to get identity Serialised template: %@ %@_%04d.bin Status message: %@ Progress %i Count of enrollments: %i BiometricKitErrorTaskCancelled BiometricKitErrorIdentityInvalid BiometricKitErrorIdentityNotAllowed BiometricKitErrorIdentityErrorInvalidData BiometricKitErrorIdentityErrorUnknown BiometricKitStatusFingerOn BiometricKitStatusFingerOff BiometricKitStatusEnrollmentComplete BiometricKitStatusEnrollmentCancelled BiometricKitStatusEnrollmentFailed BiometricKitStatusEnrollmentTimeout BiometricKitStatusUnknownError BiometricKitStatusImageRejected BiometricKitStatusNoCalibration BiometricKitImageForProcessing BiometricKitStatusTemplateListUpdated BiometricKitStatusRequestFingerOff BiometricKitStatusAutoMatchingStarted BiometricKitStatusAutoMatchingStopped BiometricKitStatusCaptureRestart BiometricKitStatusScanTooShort BiometricKitStatusAutoMatchingStartByHomeButton BiometricKitStatusMatchingCancelled BiometricKitStatusFingerOnBeforeFirstPasscodeUnlock BiometricKitStatusFingerOnInPasscodeLockout BiometricKitStatusFingerOnInBioLockout BiometricKitStatusFingerOnTokenExpired BiometricKitStatusESDRecovery BiometricKitStatusImageRejectedUnknown BiometricKitStatusImageRejectedBadBlocks BiometricKitStatusImageRejectedChFPN BiometricKitStatusImageRejectedCaFPN BiometricKitStatusSensorOperationModeIdle BiometricKitStatusSensorOperationModeCapture BiometricKitStatusSensorOperationModePause Other unknown status %i Image #%i was rejected Sensor patch version: %ld Sensor patch version: unknown Calibration Data: %@ Capture buffer: %@ Matcher: image refused Matcher: image %s node %u added as replaced Coordinates: %s[%i, %i, %i] inverse of Parent: %i Processed image: %@ Enroll debug log, version 7 static const node_placement_t table_%02i = %@{%i,%i,%i,%i,%i,%i,{ %@{%i,%i,%i,%i,%i} %@},%i,%i,%i,%i,%i,0x%04x}; bin8 bin16 binXX calibdata.bin calibration-blob Image #%i%s was sent to matcher Match result Match details: Matching score: %i Match S2S count: %i Matching node: %i Updated node: %i Not available No match (artificial) No match Image #%i Warning: the log is not complete, previous part of the log was deleted. Starting enrollment Starting matching No known identities with enroll log are available. Known identities with enroll log available: %@ : %@ Match debug log, version 7 messages.log OS version: %@ (%@) Mesa: %@ Process name:%@ PrimaryUsagePage PrimaryUsage com.apple.iokit.hid.displayStatus com.apple.mobile.keybagd.lock_status AppleMesaSEPDriver IOGeneralInterest ScanningState ScanningStateIdle ScanningStateShortScanning ScanningStateLongScanning Unknown scanning state %i Event: %@ HomeButtonPress ExtendedDeviceLockState MobileKeyBagDeviceIsUnlocked MobileKeyBagDeviceIsLocked MobileKeyBagDeviceIsLocking MobileKeyBagDisabled MobileKeyBagDeviceUnlockInProgress MobileKeyBagDeviceInGracePeriod MobileKeyBagDeviceInAssertDelay MobileKeyBagDeviceInBioUnlock Unknown lock state %i DisplayOn DisplayOff /SourceCache/Mesa/Mesa-152/AppleBiometricServices/BiometricKit/BiometricKitDebugLog.m /var/mobile/Library/Logs/CrashReporter/BiometricKit v24@0:8@"BiometricKitIdentity"16 @"NSXPCConnection" @"<BiometricKitDelegate>" @"BiometricKitXPCClient" @"BiometricKitStatistics" @"UIImage" [25{CGRect="origin"{CGPoint="x"d"y"d}"size"{CGSize="width"d"height"d}}] [25@"UIImage"] {?="count"i"capa"i"items"^^{?}"unusedImageCount"i"componentCount"i"componentCapa"i"bestComponentIndex"i"bestMapiComponentIndex"i"components"^^{?}"mapiNodeAddedIndex"s"mapiNodeRemovedIndex"s"updateCount"i"structureIsInconsistent"B} {?="nodes"[25{?="imageData"@"NSData""width"I"height"I}]} BiometricKitXpcProtocol BiometricKitDelegateXpcProtocol BiometricKitXPCClient BiometricKitTemplateInfo BiometricKitStatistics BiometricKit BiometricKitDelegate BiometricKitIdentity NSSecureCoding NSCoding BiometricKitMatchInfo BiometricKitEnrollProgressInfo BiometricKitEnrollProgressCoordinates BiometricKitEnrollProgressMergedComponent BiometricKitDebugLog