diff --git a/native/android/app/CMakeLists.txt b/native/android/app/CMakeLists.txt
--- a/native/android/app/CMakeLists.txt
+++ b/native/android/app/CMakeLists.txt
@@ -120,6 +120,7 @@
   "./src/cpp/jsiInstaller.cpp"
   "./src/cpp/NotificationsCryptoModuleJNIHelper.cpp"
   "./src/cpp/StaffUtilsJNIHelper.cpp"
+  "./src/cpp/AESCrypto.cpp"
 )
 
 list(APPEND GENERATED_NATIVE_CODE
@@ -127,7 +128,10 @@
   "../../cpp/CommonCpp/_generated/utilsJSI-generated.cpp"
   "../../cpp/CommonCpp/_generated/rustJSI-generated.cpp"
 )
-set(RUST_NATIVE_CODE "../../native_rust_library/RustCallback.cpp")
+list(APPEND RUST_NATIVE_CODE
+  "../../native_rust_library/RustCallback.cpp"
+  "../../native_rust_library/RustAESCrypto.cpp"
+)
 file(GLOB CRYPTO_NATIVE_CODE "../../cpp/CommonCpp/CryptoTools/*.cpp")
 file(GLOB DB_NATIVE_CODE "../../cpp/CommonCpp/DatabaseManagers/*.cpp")
 file(GLOB DB_ENTITIES_NATIVE_CODE "../../cpp/CommonCpp/DatabaseManagers/entities/*.cpp")
diff --git a/native/android/app/src/cpp/AESCrypto.cpp b/native/android/app/src/cpp/AESCrypto.cpp
new file mode 100644
--- /dev/null
+++ b/native/android/app/src/cpp/AESCrypto.cpp
@@ -0,0 +1,20 @@
+#include <Tools/AESCrypto.h>
+
+namespace comm {
+
+void AESCrypto::generateKey(rust::Slice<uint8_t> buffer) {
+}
+
+void AESCrypto::encrypt(
+    rust::Slice<uint8_t> key,
+    rust::Slice<uint8_t> plaintext,
+    rust::Slice<uint8_t> sealedData) {
+}
+
+void AESCrypto::decrypt(
+    rust::Slice<uint8_t> key,
+    rust::Slice<uint8_t> sealedData,
+    rust::Slice<uint8_t> plaintext) {
+}
+
+} // namespace comm
diff --git a/native/cpp/CommonCpp/Tools/AESCrypto.h b/native/cpp/CommonCpp/Tools/AESCrypto.h
new file mode 100644
--- /dev/null
+++ b/native/cpp/CommonCpp/Tools/AESCrypto.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "cxx.h"
+
+namespace comm {
+
+class AESCrypto {
+public:
+  static void generateKey(rust::Slice<uint8_t> buffer);
+  static void encrypt(
+      rust::Slice<uint8_t> key,
+      rust::Slice<uint8_t> plaintext,
+      rust::Slice<uint8_t> sealedData);
+  static void decrypt(
+      rust::Slice<uint8_t> key,
+      rust::Slice<uint8_t> sealedData,
+      rust::Slice<uint8_t> plaintext);
+};
+
+} // namespace comm
diff --git a/native/ios/Comm.xcodeproj/project.pbxproj b/native/ios/Comm.xcodeproj/project.pbxproj
--- a/native/ios/Comm.xcodeproj/project.pbxproj
+++ b/native/ios/Comm.xcodeproj/project.pbxproj
@@ -82,6 +82,8 @@
 		CBDEC69B28ED867000C17588 /* GlobalDBSingleton.mm in Sources */ = {isa = PBXBuildFile; fileRef = CBDEC69A28ED867000C17588 /* GlobalDBSingleton.mm */; };
 		CBFE58292885852B003B94C9 /* ThreadOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBFE58282885852B003B94C9 /* ThreadOperations.cpp */; };
 		D7DB6E0F85B2DBE15B01EC21 /* libPods-Comm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 994BEBDD4E4959F69CEA0BC3 /* libPods-Comm.a */; };
+		DFD5E77E2B05264000C32B6A /* AESCrypto.mm in Sources */ = {isa = PBXBuildFile; fileRef = DFD5E77D2B05264000C32B6A /* AESCrypto.mm */; };
+		DFD5E7862B052B1400C32B6A /* RustAESCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD5E7842B052B1400C32B6A /* RustAESCrypto.cpp */; };
 		F02C296C528B51ADAB5AA19D /* libPods-NotificationService.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3EE4DCB430B05EC9DE7D7B01 /* libPods-NotificationService.a */; };
 /* End PBXBuildFile section */
 
@@ -273,6 +275,10 @@
 		CBDEC69A28ED867000C17588 /* GlobalDBSingleton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = GlobalDBSingleton.mm; path = Comm/GlobalDBSingleton.mm; sourceTree = "<group>"; };
 		CBFE58272885852B003B94C9 /* ThreadOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadOperations.h; path = PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.h; sourceTree = "<group>"; };
 		CBFE58282885852B003B94C9 /* ThreadOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadOperations.cpp; path = PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.cpp; sourceTree = "<group>"; };
+		DFD5E77D2B05264000C32B6A /* AESCrypto.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AESCrypto.mm; path = Comm/AESCrypto.mm; sourceTree = "<group>"; };
+		DFD5E7802B05264F00C32B6A /* AESCrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AESCrypto.h; sourceTree = "<group>"; };
+		DFD5E7842B052B1400C32B6A /* RustAESCrypto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RustAESCrypto.cpp; sourceTree = "<group>"; };
+		DFD5E7852B052B1400C32B6A /* RustAESCrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RustAESCrypto.h; sourceTree = "<group>"; };
 		F53DA7B3F26C2798DCE74A94 /* Pods-Comm.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Comm.debug.xcconfig"; path = "Target Support Files/Pods-Comm/Pods-Comm.debug.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
@@ -358,6 +364,7 @@
 		71B8CCB626BD30EC0040C0A2 /* CommCoreImplementations */ = {
 			isa = PBXGroup;
 			children = (
+				DFD5E77D2B05264000C32B6A /* AESCrypto.mm */,
 				CBCF57A92B05091D00EC4BC0 /* CommAESCryptoUtils */,
 				CB90951729531647002F2A7F /* CommIOSNotifications */,
 				8E43C32E291E5B9D009378F5 /* TerminateApp.h */,
@@ -401,6 +408,7 @@
 		71BE84382636A944002849D2 /* Tools */ = {
 			isa = PBXGroup;
 			children = (
+				DFD5E7802B05264F00C32B6A /* AESCrypto.h */,
 				CBCA09052A8E0E6B00F75B3E /* StaffUtils.cpp */,
 				CBCA09042A8E0E6B00F75B3E /* StaffUtils.h */,
 				7FBB2A7A29EEA2A4002C6493 /* Base64.cpp */,
@@ -579,6 +587,8 @@
 		8B99AF6B28D50D4800EB5ADB /* native_rust_library */ = {
 			isa = PBXGroup;
 			children = (
+				DFD5E7842B052B1400C32B6A /* RustAESCrypto.cpp */,
+				DFD5E7852B052B1400C32B6A /* RustAESCrypto.h */,
 				8B652FA4295EA9F1009F8163 /* RustCallback.h */,
 				8B99BAAD28D511FF00EB5ADB /* lib.rs.cc */,
 				8B99AF6D28D50D4800EB5ADB /* lib.rs.h */,
@@ -1088,6 +1098,7 @@
 				71142A7726C2650B0039DCBD /* CommSecureStoreIOSWrapper.mm in Sources */,
 				7FBB2A7B29EEA2A4002C6493 /* Base64.cpp in Sources */,
 				CB38F2B1286C6C870010535C /* MessageOperationsUtilities.cpp in Sources */,
+				DFD5E7862B052B1400C32B6A /* RustAESCrypto.cpp in Sources */,
 				8EF775712A751B780046A385 /* ReportStore.cpp in Sources */,
 				71CA4A64262DA8E500835C89 /* Logger.mm in Sources */,
 				71BF5B7F26BBDD7400EDE27D /* CryptoModule.cpp in Sources */,
@@ -1099,6 +1110,7 @@
 				711B408425DA97F9005F8F06 /* dummy.swift in Sources */,
 				8E86A6D329537EBB000BBE7D /* DatabaseManager.cpp in Sources */,
 				CBDEC69B28ED867000C17588 /* GlobalDBSingleton.mm in Sources */,
+				DFD5E77E2B05264000C32B6A /* AESCrypto.mm in Sources */,
 				8EA59BD62A6E8E0400EB4F53 /* DraftStore.cpp in Sources */,
 				13B07FC11A68108700A75B9A /* main.m in Sources */,
 				71BE844B2636A944002849D2 /* SQLiteQueryExecutor.cpp in Sources */,
diff --git a/native/ios/Comm/AESCrypto.mm b/native/ios/Comm/AESCrypto.mm
new file mode 100644
--- /dev/null
+++ b/native/ios/Comm/AESCrypto.mm
@@ -0,0 +1,20 @@
+#import "AESCrypto.h"
+
+namespace comm {
+
+void AESCrypto::generateKey(rust::Slice<uint8_t> buffer) {
+}
+
+void AESCrypto::encrypt(
+    rust::Slice<uint8_t> key,
+    rust::Slice<uint8_t> plaintext,
+    rust::Slice<uint8_t> sealedData) {
+}
+
+void AESCrypto::decrypt(
+    rust::Slice<uint8_t> key,
+    rust::Slice<uint8_t> sealedData,
+    rust::Slice<uint8_t> plaintext) {
+}
+
+} // namespace comm
diff --git a/native/native_rust_library/RustAESCrypto.h b/native/native_rust_library/RustAESCrypto.h
new file mode 100644
--- /dev/null
+++ b/native/native_rust_library/RustAESCrypto.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "cxx.h"
+
+namespace comm {
+
+void aesGenerateKey(rust::Slice<uint8_t> buffer);
+void aesEncrypt(rust::Slice<uint8_t> key, rust::Slice<uint8_t> plaintext, rust::Slice<uint8_t> sealedData);
+void aesDecrypt(rust::Slice<uint8_t> key, rust::Slice<uint8_t> sealedData, rust::Slice<uint8_t> plaintext);
+
+} // namespace comm
diff --git a/native/native_rust_library/RustAESCrypto.cpp b/native/native_rust_library/RustAESCrypto.cpp
new file mode 100644
--- /dev/null
+++ b/native/native_rust_library/RustAESCrypto.cpp
@@ -0,0 +1,18 @@
+#include "RustAESCrypto.h"
+#include "../cpp/CommonCpp/Tools/AESCrypto.h"
+
+namespace comm {
+
+void aesGenerateKey(rust::Slice<uint8_t> buffer){
+  AESCrypto::generateKey(buffer);
+}
+
+void aesEncrypt(rust::Slice<uint8_t> key, rust::Slice<uint8_t> plaintext, rust::Slice<uint8_t> sealedData){
+  AESCrypto::encrypt(key, plaintext, sealedData);
+}
+
+void aesDecrypt(rust::Slice<uint8_t> key, rust::Slice<uint8_t> sealedData, rust::Slice<uint8_t> plaintext){
+  AESCrypto::decrypt(key, sealedData, plaintext);
+}
+
+}
diff --git a/native/native_rust_library/src/constants.rs b/native/native_rust_library/src/constants.rs
new file mode 100644
--- /dev/null
+++ b/native/native_rust_library/src/constants.rs
@@ -0,0 +1,6 @@
+#[allow(unused)]
+pub mod aes {
+  pub const KEY_SIZE: usize = 32; // bytes
+  pub const IV_LENGTH: usize = 12; // bytes - unique Initialization Vector (nonce)
+  pub const TAG_LENGTH: usize = 16; // bytes - GCM auth tag
+}
diff --git a/native/native_rust_library/src/lib.rs b/native/native_rust_library/src/lib.rs
--- a/native/native_rust_library/src/lib.rs
+++ b/native/native_rust_library/src/lib.rs
@@ -18,6 +18,7 @@
 use tracing::instrument;
 
 mod argon2_tools;
+mod constants;
 
 use argon2_tools::compute_backup_key;
 
@@ -143,6 +144,36 @@
     #[cxx_name = "boolCallback"]
     fn bool_callback(error: String, promise_id: u32, ret: bool);
   }
+
+  // AES cryptography
+  #[namespace = "comm"]
+  unsafe extern "C++" {
+    include!("RustAESCrypto.h");
+
+    #[allow(unused)]
+    #[cxx_name = "aesGenerateKey"]
+    fn generate_key(buffer: &mut [u8]) -> Result<()>;
+
+    /// The first two argument aren't mutated but creation of Java ByteBuffer
+    /// requires the underlying bytes to be mutable.
+    #[allow(unused)]
+    #[cxx_name = "aesEncrypt"]
+    fn encrypt(
+      key: &mut [u8],
+      plaintext: &mut [u8],
+      sealed_data: &mut [u8],
+    ) -> Result<()>;
+
+    /// The first two argument aren't mutated but creation of Java ByteBuffer
+    /// requires the underlying bytes to be mutable.
+    #[allow(unused)]
+    #[cxx_name = "aesDecrypt"]
+    fn decrypt(
+      key: &mut [u8],
+      sealed_data: &mut [u8],
+      plaintext: &mut [u8],
+    ) -> Result<()>;
+  }
 }
 
 fn handle_string_result_as_callback<E>(