Một phương pháp mã hóa phân vùng dữ liệu trên máy tính nhúng (Phần I)
CÁC PHƯƠNG PHÁP MÃ HÓA LƯU TRỮ
Có thể chia các phương pháp mã hóa lưu trữ thành hai nhóm phương pháp chính, đó là: mã hóa có chứa hệ điều hành và mã hóa không chứa hệ điều hành.
Phương pháp mã hóa dữ liệu có chứa hệ điều hành: toàn bộ dữ liệu bao gồm cả hệ điều hành, tập tin hệ thống (file system), vùng RAM ảo (swap) đều được mã hóa. Để truy cập, thiết bị sẽ khởi động Bootloader đã được cài đặt để xác thực và giải mã phân vùng chứa hệ điều hành. Đây là cách tốt để bảo vệ dữ liệu trong trường hợp dữ liệu bị mất cắp hoặc thất lạc. Nhược điểm của phương pháp này là hiệu suất thực thi của thiết bị sẽ bị ảnh hưởng bởi phải liên tục mã hóa và giải mã dữ liệu trong quá trình nạp các tiến trình của hệ điều hành và các ứng dụng, ngoài ra việc sao lưu dữ liệu phức tạp có thể dẫn đến nguy cơ mất toàn bộ dữ liệu nếu bộ nhớ bị lỗi phần cứng.
Phương pháp mã hóa dữ liệu không chứa hệ điều hành: gồm mã hóa tệp và thư mục, mã hóa phân vùng, mã hóa Container. Trong đó mã hóa tệp và thư mục được thực hiện riêng rẽ, tuy nhiên do mã hóa tệp tận dụng hạ tầng có sẵn của tập tin hệ thống nên chỉ có phần nội dung của tệp được mã hóa, còn các thông tin như cấu trúc thư mục, tên tệp, thời gian tạo tệp,… thì không. Mã hóa phân vùng không chứa hệ điều hành là một cách an toàn để bảo vệ dữ liệu lưu trữ, người dùng có thể lựa chọn phân vùng để mã hóa và cần phải xác thực để quá trình giải mã có thể diễn ra, sau khi liên kết phân vùng đó, dữ liệu mà người dùng nhìn thấy là dữ liệu rõ nhưng thực chất là được lưu trữ dưới dạng mã hóa trên ổ đĩa, sau khi kết thúc quá trình làm việc, người dùng có thể bỏ liên kết và dữ liệu trên phân vùng mã hóa không thể truy cập được. Mã hóa Container được coi là mềm dẻo hơn so với mã hóa phân vùng, các tệp và thư mục có thể mở ra khi sử dụng và đóng khi kết thúc, tuy nhiên cơ chế này sử dụng RAM để lưu trữ, điều này ít khi được sử dụng trên thiết bị IoT vốn chỉ có tài nguyên hạn chế.
Mục đích của bài báo hướng tới một giải pháp mã hóa dữ liệu lưu trữ trên các thiết bị nhúng IoT, vì vậy mã hóa phân vùng không chứa hệ điều hành là giải pháp phù hợp cho những ứng dụng yêu cầu truy xuất thường xuyên đến một phân vùng cụ thể.
Hiện nay có rất nhiều phần mềm mã hóa thương mại và mã nguồn mở. Về phương diện phần mềm thương mại, nổi bật có thể nhắc đến BitLocker, EFS, TrustedDisk,… Trong những phần mềm này, tiến trình mã hóa, giải mã sẽ được thực thi dưới kernel, sau đó đi qua driver và ghi xuống ổ đĩa cứng. Có thể thấy các phần mềm thương mại đều hỗ trợ đầy đủ các tính năng và hoạt động ổn định, tuy nhiên hầu hết các phần mềm này đều không có độ tùy biến cao và bị hạn chế bởi các nhà phát triển.
Đối với các phần mềm mã hóa mã nguồn mở có độ tùy biến và hỗ trợ nhiều giải pháp mã hóa như DiskCryptor, TrueCrypt, VeraCrypt,… Nhưng số lượng phần mềm tương thích tốt với máy tính nhúng nền tảng ARM là không nhiều. LUKS là một công cụ mã hóa phân vùng dựa trên dm-crypt được sử dụng rất nhiều trên hệ điều hành Linux [4]. Ứng dụng này hỗ trợ tùy biến cao và có thể chạy ổn định với các loại máy tính nhúng phổ biến hiện nay như Raspberry Pi, Nvidia Jetson Nano, LattePanda, BeagleBone Black.
MÃ HÓA PHÂN VÙNG BẰNG DM-CRYPT VÀ LUKS TRÊN RASPBERRY PI
Mã hóa phân vùng sử dụng module dm-crypt
Dm-crypt là một module dùng để mã hóa dựa trên cấu trúc Device Mapper trong Linux Kernel [7]. Dm-crypt sử dụng nguyên lý của Device Mapper để mã hóa dữ liệu thông qua khối ảo từ việc địa chỉ hóa khối thực thành khối ảo. Quá trình đọc và ghi trên thiết bị khối thực sẽ thông qua khối ảo. Các hoạt động mã hóa được thực hiện bằng cách sử dụng gán tham số mã hóa khi khởi tạo các thiết bị khối ảo và sử dụng Linux Crypto API để thực hiện việc mã hóa và giải mã.
Hình 1. Vị trí của dm-crypt trong hệ thống
Như mô tả trong Hình 1, dm-crypt nằm giữa Filesystem và Physical Drive, có nhiệm vụ mã hóa dữ liệu từ những lớp trên và ghi xuống. Trong quá trình đọc dữ liệu, dữ liệu mã từ Physical Drive sẽ được giải mã thành dữ liệu rõ trước khi đưa lại lên tầng Application. Vì vậy dữ liệu được lưu trong Physical Drive là dữ liệu mã đã được mã hóa và bảo vệ.
Hình 2. Xử lý đọc/ghi dữ liệu mã trên dm-crypt và CryptoAPI
Hình 2 mô tả quá trình đọc/ghi dữ liệu dưới kernel. Trong tác vụ ghi dữ liệu (mũi tên màu đỏ), khi hệ thống đưa ra yêu cầu ghi, dm-crypt sẽ đặt tiến trình vào trong một hàng đợi (workqueue) có tên là “kcryptd” để lập lịch cho tác vụ đó. Khi có đủ điều kiện (nhân Crypto rảnh) thì sẽ gửi dữ liệu đến Crypto API để mã hóa.
Trong tác vụ đọc dữ liệu lên Filesystem (được biểu diễn bằng những mũi tên màu xanh), sẽ có 2 luồng thông tin: Một là tín hiệu Request gửi từ Filesystem xuống Block device drivers để yêu cầu địa chỉ và độ dài dữ liệu cần đọc; hai là dữ liệu gửi qua Crypto API để giải mã và trả lại Filesystem. Khối Crypto API chứa những module mã hóa trong kernel bao gồm thuật toán mã khối, các hàm băm và kiểm dư chu trình (Cyclic Redundancy Check - CRC).
Mã hóa phân vùng sử dụng LUKS
LUKS (Linux Unified Key Setup) là một công cụ của dm-crypt, có thể được hiểu là một định dạng mã hóa dữ liệu trên phân vùng ổ đĩa, dùng một cụm mật khẩu hoặc keyfile để mã hóa và giải mã. Các tiến trình hoạt động như tạo phân vùng mã hóa, mở và truy cập các phân vùng mã hóa, định nghĩa và thêm khóa được thực hiện thông qua việc sử dụng thư viện cryptsetup. LUKS có những ưu điểm như: Khả năng tương thích với các chuẩn trong các hệ điều hành Linux; cung cấp và thu hồi mật khẩu hiệu quả; hỗ trợ nhiều định dạng khóa, có thể là passphrase hoặc keyfile; khả năng tùy biến cao trên các hàm mã hóa và hàm băm. Ngoài ra, LUKS hoạt động tốt với các nền tảng Linux trên nền tảng ARM như Raspberry Pi hay Nvidia Jetson Nano, qua đó phù hợp với những thiết bị thông minh đang rất phổ biến hiện nay. LUKS hỗ trợ các thuật toán mã hóa mặc định như: AES, Twofish, Serpent cùng với chế độ mã hóa như XTS, CBC,... và kết hợp với vector khởi tạo là plain64 hoặc ESSIV (Encrypted Salt-Sector Initialization Vector) [1].
LUKS sử dụng PBKDF2 kết hợp với các thuật toán hàm băm như SHA1, SHA256, SHA512, Ripemd160 hay Whirlpool với số lần lặp lớn để tạo ra khóa.
Thư viện cryptsetup cung cấp công cụ benchmark để kiểm tra tốc độ thực thi các thuật toán khi đọc và ghi trên RAM. Trong bài toán thực tế, dữ liệu được truy xuất từ phân vùng vật lý của ổ đĩa, vì vậy tốc độ đọc ghi thực tế cũng phụ thuộc vào tốc độ làm việc trên ổ đĩa.
(a) Tốc độ thực thi thuật toán AES, SERPENT, TWOFISH chế độ XTS
(b) Tốc độ thực thi AES-XTS khóa 512 bit trên các phiên bản Raspberry Pi
(c) Tốc độ thực thi thuật toán AES với chế độ ECB, CBC, XTS, CTR trên Raspberry Pi 3
Hình 3. Tốc độ thực thi các thuật toán mật mã
Hình 3(a) so sánh tốc độ mã hóa và giải mã của các thuật toán AES, Serpent và Twofish trên cùng một cấu trúc phần cứng Raspberry Pi 3 và đều sử dụng chế độ XTS. Với những hệ thống hỗ trợ “hệ tập lệnh cải thiện tính toán đa nhân cho thuật toán AES” AES-NI thì tốc độ mã hóa/giải mã của AES rất cao, như ta thấy trên Hình 3, tốc độ AES vượt trội so với các thuật toán khác như Serpent hay Twofish. Ba thuật toán này đều có độ bảo mật cao và người dùng có thể lựa chọn sử dụng tùy theo từng ứng dụng.
Hình 3(b) biểu diễn sự khác nhau giữa tốc độ thực thi thuật toán mật mã với các chế độ hoạt động khác nhau trên Raspberry Pi 3, các chế độ so sánh gồm ECB, CBC, XTS và CTR, đây đều là những chế độ mã hóa phân vùng lưu trữ được sử dụng phổ biến. Ta có thể thấy ở các chế độ ECB, XTS và CTR tốc độ mã hóa/giải mã đều không có sự khác biệt quá nhiều, trong khi đối với chế độ CBC, tốc độ giải mã nhanh hơn tốc độ mã hóa rất nhiều. Điều này là do chế độ CBC chỉ có thể thực hiện tính toán song song ở tiến trình giải mã, còn ở chế độ mã hóa chỉ có thể thực thi tuần tự. Vì vậy lựa chọn chế độ làm việc của thuật toán mật mã cũng rất quan trọng và phụ thuộc vào từng ứng dụng, chế độ XTS được khuyến khích sử dụng do có những ưu điểm trong bảo mật dữ liệu lưu trữ [2, 5].
Để khảo sát ảnh hưởng của phần cứng tới tốc độ mã hóa/giải mã, thực hiện benchmark trên các phiên bản của Raspberry Pi từ 2 đến 4 với thuật toán mật mã AES chế độ XTS, độ dài khóa 512 bit ta thu được kết quả như hình 3(c). Ta thấy có sự khác biệt rất đáng kể giữa các phiên bản trong tốc độ thực thi. Raspberry Pi 2 sử dụng chip Cortex-A7 cho kết quả chỉ khoảng 20 MiB/s, trong khi đó đối với Raspberry Pi 4 dùng chip Cortex-A72, con số này là khoảng 68 MiB/s đối với mã hóa và khoảng 59 MiB/s đối với giải mã. Qua đó có thể đưa ra được sự lựa chọn về phần cứng đối với từng loại ứng dụng. Ví dụ đối với những ứng dụng cần thông lượng trao đổi dữ liệu lớn như NAS thì ưu tiên sử dụng phần cứng mạnh mẽ như phiên bản Raspberry Pi 4, còn với những ứng dụng như bảo mật tập tin âm thanh hay video từ camera thì phiên bản Raspberry Pi 3 hoàn toàn có thể đáp ứng được.
Ngoài ra, có thể tích hợp thêm thuật toán mật mã lên thiết bị để phù hợp với những ứng dụng bảo mật riêng tư. Như đã trình bày trong Hình 2, Crypto API chứa module mật mã và nhà phát triển hoàn toàn có thể thêm hoặc bớt đi những module mật mã này. Hệ điều hành Raspbian được phát triển từ Linux, có hỗ trợ thêm hoặc bớt module thuật toán vào kernel, việc này sẽ làm thay đổi kích thước kernel. Để không làm nhân quá lớn, giải pháp tích hợp là thiết kế các module dưới dạng tách rời. Trong quá trình hoạt động, module nào cần thiết sẽ được gắn vào kernel, còn module nào không cần thiết sẽ bị tháo ra khỏi kernel, ta không cần phải biên dịch lại toàn bộ kernel khi thêm mới hoặc thay đổi module.
KẾT LUẬN
Phần I của bài báo đã trình bày về các giải pháp mã hóa dữ liệu lưu trữ, giới thiệu nguyên lý hoạt động và một số công cụ phần mềm hỗ trợ mã hóa dữ liệu cả về thương mại lẫn mã nguồn mở, tìm hiểu sâu hơn về giải pháp mã hóa phân vùng bằng dm-crypt và LUKS trên máy tính nhúng Raspberry Pi. Đồng thời, khảo sát một số thuật toán mật mã khi thực thi trên các phiên bản Raspberry Pi, qua đó giúp cho việc lựa chọn thuật toán và phần cứng vào các ứng dụng cụ thể.
Với những ưu điểm của việc thiết kế module dưới dạng tách rời, nhóm tác giả xây dựng một module Kuznyechik trong chuẩn mật mã GOST R34.12-2015 để tích hợp vào ứng dụng mã hóa phân vùng sẽ giới thiệu đến bạn đọc trong Phần II tiếp theo.
TÀI LIỆU THAM KHẢO [1]. NIST Computer Security Division’s, Security Technology Group, “Block cipher modes”. Cryptographic Toolkit. NIST. Archived from the original on November 6, 2012. Retrieved April 12, 2013. [2]. Shrestha, Muna, “Parallel Implementation of AES using XTS Mode of Operation”, Culminating Projects in Computer Science and Information Technology 21, 2018. [3]. V. Dolmatov, Ed., “GOST R 34.12-2015: Block Cipher “Kuznyechik””, Research Computer Center MSU, 2016. [4]. Clemens Fruhwirth, “LUKS1 On-Disk Format Specifiation”, 2018. [5]. Matthew V. Ball, Cyril Guyot, James P. Hughes, Luther Martin & Landon Curt Noll, “The XTS-AES Disk Encryption Algorithm and the Security of Ciphertext Stealing”, Cryptologia, Volume 36, 2012 - Issue 1, 2012. [6]. Wenger, “RTP Payload Format for H.264 Video”, RFC 3984, 2005. [7]. Mike Peters, “Encrypting partitions using dm-crypt and the 2.6 series kernel”, dm-crypt Project, 2012. |
Nguyễn Ngọc Quỳnh, TS. Nguyễn Chung Tiến, TS. Đỗ Cao Khánh (Học viện Kỹ thuật mật mã)