Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3370264
D7005.id23841.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Referenced Files
None
Subscribers
None
D7005.id23841.diff
View Options
diff --git a/native/expo-modules/aes-crypto/ios/AESCryptoModule.swift b/native/expo-modules/aes-crypto/ios/AESCryptoModule.swift
--- a/native/expo-modules/aes-crypto/ios/AESCryptoModule.swift
+++ b/native/expo-modules/aes-crypto/ios/AESCryptoModule.swift
@@ -2,12 +2,15 @@
import CryptoKit
private let KEY_SIZE = 32 // bytes
+private let IV_LENGTH = 12 // bytes, IV - unique Initialization Vector (nonce)
+private let TAG_LENGTH = 16 // bytes - GCM auth tag
public class AESCryptoModule: Module {
public func definition() -> ModuleDefinition {
Name("AESCrypto")
Function("generateKey", generateKey)
+ Function("encrypt", encrypt)
}
}
@@ -23,9 +26,38 @@
}
}
+private func encrypt(rawKey: Uint8Array,
+ plaintext: Uint8Array,
+ destination: Uint8Array) throws {
+ guard destination.byteLength == plaintext.byteLength + IV_LENGTH + TAG_LENGTH
+ else {
+ throw InvalidDataLengthException()
+ }
+
+ let key = SymmetricKey(data: rawKey.data())
+ let iv = AES.GCM.Nonce()
+ let encryptionResult = try AES.GCM.seal(plaintext.data(),
+ using: key,
+ nonce: iv)
+
+ // 'combined' returns concatenated: iv || ciphertext || tag
+ guard let sealedData = encryptionResult.combined else {
+ // this happens only if Nonce/IV != 12 bytes long
+ throw EncryptionFailedException("Incorrect AES configuration")
+ }
+ guard sealedData.count == destination.byteLength else {
+ throw EncryptionFailedException("Encrypted data has unexpected length")
+ }
+ sealedData.copyBytes(to: destination.rawBufferPtr())
+}
+
// MARK: - Utilities
extension TypedArray {
+ func data() -> Data {
+ Data(bytes: self.rawPointer, count: self.byteLength)
+ }
+
func rawBufferPtr() -> UnsafeMutableRawBufferPointer {
UnsafeMutableRawBufferPointer(start: self.rawPointer,
count: self.byteLength)
@@ -39,3 +71,15 @@
"The AES key has invalid length"
}
}
+
+private class InvalidDataLengthException: Exception {
+ override var reason: String {
+ "Source or destination array has invalid length"
+ }
+}
+
+private class EncryptionFailedException: GenericException<String> {
+ override var reason: String {
+ "Failed to encrypt data: \(param)"
+ }
+}
diff --git a/native/utils/aes-crypto-module.js b/native/utils/aes-crypto-module.js
--- a/native/utils/aes-crypto-module.js
+++ b/native/utils/aes-crypto-module.js
@@ -1,11 +1,19 @@
// @flow
import { requireNativeModule } from 'expo-modules-core';
+import invariant from 'invariant';
const KEY_SIZE = 32; // bytes
+const IV_LENGTH = 12; // bytes, IV - unique Initialization Vector (nonce)
+const TAG_LENGTH = 16; // bytes - GCM auth tag
const AESCryptoModule: {
+generateKey: (destination: Uint8Array) => void,
+ +encrypt: (
+ key: Uint8Array,
+ data: Uint8Array,
+ destination: Uint8Array,
+ ) => void,
} = requireNativeModule('AESCrypto');
export function generateKey(): Uint8Array {
@@ -13,3 +21,10 @@
AESCryptoModule.generateKey(keyBuffer);
return keyBuffer;
}
+
+export function encrypt(key: Uint8Array, data: Uint8Array): Uint8Array {
+ invariant(AESCryptoModule.encrypt, 'AESCrypto.encrypt is not implemented');
+ const sealedDataBuffer = new Uint8Array(data.length + IV_LENGTH + TAG_LENGTH);
+ AESCryptoModule.encrypt(key, data, sealedDataBuffer);
+ return sealedDataBuffer;
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 27, 1:40 AM (9 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2587273
Default Alt Text
D7005.id23841.diff (3 KB)
Attached To
Mode
D7005: [native][AES] Implement encrypt function on iOS
Attached
Detach File
Event Timeline
Log In to Comment