Hỗ trợ mã hóa cứng AES trên vi xử lý Intel

15:00 | 24/12/2013

AES là thuật toán mã khối được chính phủ Hoa Kỳ áp dụng làm tiêu chuẩn mã hóa từ năm 2001. Các nghiên cứu cho thấy AES là hệ mật an toàn và hiệu quả, do đó AES được sử dụng rộng rãi cho cả các cơ quan chính phủ và các lĩnh vực khác. Hiện nay, hầu hết các hệ thống công nghệ thông tin có sử dụng mật mã đều hỗ trợ AES. Bài báo này giới thiệu một sự hỗ trợ đặc biệt cho AES trong các dòng vi xử lý Intel hiện đại.


Nhu cầu cứng hóa thuật toán mật mã

Ngày nay, rất nhiều hệ mật có chất lượng tốt được công bố công khai, việc đưa một hệ mật nào đó vào sử dụng là một vấn đề tương đối đơn giản. Có rất nhiều thư viện lập trình, bao gồm cả những sản phẩm mã nguồn mở, sản phẩm miễn phí, sản phẩm thương mại hỗ trợ các hàm để làm việc với các hệ mật khác nhau. Với sự hỗ trợ của các thư viện lập trình này, người ta có thể nhanh chóng xây dựng được các sản phẩm phần mềm có sử dụng mật mã để bảo vệ thông tin mà thậm chí không cần biết đến bản chất của các hệ mật. Trong môi trường máy tính và mạng máy tính, ta rất dễ bắt gặp ứng dụng của việc cài đặt mềm các hệ mật như thế. Đó là khi sử dụng giao thức HTTPS để duyệt web, sử dụng SMIME hay PGP để gửi thư điện tử an toàn, sử dụng BitLocker trong hệ điều hành Windows để mã hóa ổ đĩa, sử dụng TrueCrypt hay CryptoDisk để tạo ra các đĩa ảo mật mã….
Việc sử dụng mật mã mang lại lợi ích to lớn trong đảm bảo an toàn thông tin, mật mã cho phép thực hiện các dịch vụ đảm bảo bí mật, toàn vẹn, xác thực nguồn gốc dữ liệu, chống chối bỏ trong quá trình trao đổi, lưu trữ thông tin. Tuy nhiên, việc sử dụng mật mã cũng có nhược điểm đáng kể: các phép biến đổi mật mã đòi hỏi sử dụng lượng lớn tài nguyên tính toán; trên cùng một hệ thống thì việc sử dụng mật mã sẽ làm chậm quá trình xử lý thông tin, làm giảm hiệu năng của hệ thống. Như vậy, bên cạnh vấn đề an toàn của hệ mật thì một vấn đề khác cũng rất được quan tâm khi sử dụng mật mã là tăng tốc các phép biến đổi mật mã.
Thông thường trong các phần mềm, phép mã hóa chủ yếu được thực hiện thông qua các lệnh toán học đa dụng của các vi xử lý. Rõ ràng là cách cài đặt như thế chưa hiệu quả vì phải tốn nhiều thời gian cho quá trình vào/ra dữ liệu giữa bộ nhớ RAM và vi xử lý. Nếu xét riêng hệ mật AES thì hộp thế S-box được lưu trữ trong RAM, khiến thời gian thực hiện phép thay thế sẽ lớn hơn đáng kể so với trường hợp hộp thế được lưu trong chính vi xử lý.
Để giải quyết vấn đề này, hai hãng sản xuất vi xử lý máy tính hàng đầu thế giới là Intel và AMD đã đưa vào các dòng vi xử lý mới nhất một tập lệnh để hỗ trợ mã hóa cứng cho hệ mật AES.
Dưới đây giới thiệu tập lệnh AES - NI (New Instructions - NI) được hỗ trợ bởi các dòng vi xử lý mới của Intel.

  Tập lệnh AES-NI của vi xử lý Intel

Hệ mật AES được các chuyên gia đánh giá cao cả về tính an toàn và hiệu năng so với các hệ mật khác, nên người ta dự đoán rằng AES sẽ là hệ mật quan trọng và được sử dụng lâu dài. Do đó, việc phát triển và cải thiện về hiệu suất, an toàn trong cài đặt AES sẽ rất có lợi cho các hệ thống máy tính.

Hình 1. So sánh thời gian mã hóa giữa các hệ mật
Việc hỗ trợ tập lệnh dành riêng cho cài đặt AES, gọi là AES-NI, đã được Intel triển khai từ năm 2010. Đến nay đã có khá nhiều dòng vi xử lý của Intel hỗ trợ tập lệnh này:
- Vi xử lý Intel dành cho máy chủ: AES-NI được hỗ trợ trên Intel Westmere-EP, Intel Clark thế hệ thứ 3, Intel Arrandale thế hệ thứ 3 và Core i5-4xxM.
- Vi xử lý Intel Sandy Bridge: Dòng vi xử lý dành cho máy để bàn: AES-NI được hỗ trợ bởi tất cả vi xử lý Pentium, Celeron và Core thế hệ thứ 3; Dòng vi xử lý dành cho máy tính xách tay: AES-NI được hỗ trợ bởi tất cả vi xử lý Intel Core thế hệ thứ 5 và thứ 7.
- Vi xử lý Intel Ivy Bridge: AES-NI được hỗ trợ bởi tất cả các vi xử lý thế hệ thứ 5, thứ 7, Xeon và thế hệ thứ 3 i3-2115C.
- Vi xử lý Intel Haswell: hỗ trợ tất cả các vi xử lý Intel Pentium và Celeron.
Một số dòng vi xử lý Intel khác.
Tập lệnh AES-NI khá đơn giản, bao gồm 6 lệnh Assembly. Trong số 6 lệnh này thì có 4 lệnh được dùng để hỗ trợ việc mã hóa và giải mã là AESENC, AESENCLAST, AESDEC, AESDECLAST; 2 lệnh còn lại được dùng để sinh các khóa vòng từ khóa chính là AESIMC và AESKEYGENASSIST. Tất cả các lệnh này đều yêu cầu phải làm việc với ô nhớ hay thanh ghi 128 bit. Trong vi xử lý Intel có 16 thanh ghi 128 bit được ký hiệu từ xmm0 đến xmm15. Sau đây ta sẽ xem xét sơ lược về các lệnh AES-NI.
Lệnh tạo khóa vòng mã hóa
AESKEYGENASSIST xmm1, xmm2/[m128], imm8
Tham số:
xmm1 (out): thanh ghi 128 bit chứa khóa vòng được tạo ra
xmm2/[m128] (in): thanh ghi/vùng nhớ 128 bit chứa khóa chính
imm8(in): giá trị tức thời 8 bit biểu thị cho Rcon (Round Constants)
Mô tả: Lệnh trên sẽ sinh ra một khóa vòng từ khóa chính. Khóa chính được lưu trong một thanh ghi (xmm2) hoặc bộ nhớ 128 bit. Khóa vòng sẽ khác nhau cho từng vòng, sự khác nhau được quyết định bởi giá trị Rcon (Round constants). Trong thủ tục tạo khóa vòng AES (AES Key Schedule), giá trị Rcon ứng với vòng thứ i được xác định bởi
rcon (i) = x (i-1) mod x8  +  x4 + x3 + x1 trong trường F28 . Đối với AES-128 thì i nhận giá trị từ 0 đến 10, giá trị của các Rcon(i) tương ứng sẽ là {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}. Kết quả được lưu vào một thanh ghi (xmm1) 128 bit. Ví dụ, nếu khóa chính được lưu trong thanh ghi xmm0 và ta muốn tạo khóa vòng cho vòng thứ 4, ghi kết quả vào thanh ghi xmm4 thì cần gọi lệnh
AESKEYGENASSIST xmm4,xmm0,8
Bằng cách gọi nhiều lần câu lệnh AESKEYGENASSIST, người ta sẽ tạo ra được số khóa vòng cần thiết cho việc mã hóa.
Lệnh tạo khóa vòng giải mã
AESIMC xmm1, xmm2/[m128]
Tham số:
xmm1 (out): chứa khóa vòng được tạo ra
xmm2/[m128] (in): chứa khóa vòng mã hóa được tạo ra bằng lệnh AESKEYGENASSIST trên đây.
Mô tả: Câu lệnh này thực hiện biến đổi ngược InvMixColumn trên khóa vòng mã hóa (có độ dài 128 bit) được lưu trong thanh ghi hoặc ô nhớ 128 bit (xmm2/[m128]). Kết quả sẽ được lưu trữ vào thanh ghi 128 bit (xmm1).
Lệnh mã hóa
AESENC xmm1, xmm2/[m128]
AESENCLAST xmm1, xmm2/[m128]

Tham số:
xmm1 (in-out): ban đầu, thanh ghi này chứa mảng trạng thái (State) cần được mã hóa; khi việc mã hóa hoàn tất thì kết quả được đưa vào chính thanh ghi này và nó đóng vai trò đầu vào cho mã hóa vòng kế tiếp;
xmm2/[m128] (in): chứa khóa vòng mã hóa
Mô tả: Câu lệnh này sẽ thực hiện mã hóa 128 bit dữ liệu bằng một vòng AES, sử dụng 128 bit khóa vòng. Dữ liệu được chứa trong thanh ghi 128 bit, khóa vòng có thể được chứa trong thanh ghi hoặc trong bộ nhớ. Điểm khác nhau giữa hai lệnh AESENC và AESENLAST là ở chỗ: lệnh AESENCLAST được sử dụng để mã hóa vòng cuối cùng, còn lệnh AESENC được sử dụng để mã hóa (lần lượt) tất cả các vòng còn lại. Ví dụ: trong AES-128, một khối dữ liệu phải được mã hóa qua 10 vòng và có thể được thực hiện bằng việc sử dụng các câu lệnh trên như sau:
Lệnh mã hóa
AESDEC xmm1, xmm2/[m128]
AESDECLAST xmm1, xmm2/[m128]

Tham số:
xmm1 (in-out): ban đầu, thanh ghi này chứa mảng trạng thái (State) cần được giải mã; khi việc giải mã hoàn tất thì kết quả được đưa vào chính thanh ghi này và nó đóng vai trò đầu vào cho giải mã ở vòng kế tiếp;
xmm2/[m128] (in): chứa khóa vòng giải mã
Mô tả: Câu lệnh này sẽ thực hiện giải mã 128 bit dữ liệu bằng một vòng AES, sử dụng 128 bit khóa vòng. Dữ liệu được chứa trong thanh ghi 128 bit, khóa vòng có thể được chứa trong thanh ghi hoặc trong bộ nhớ. Điểm khác nhau giữa hai lệnh AESDEC và AESDECLAST là ở chỗ: lệnh AESDECLAST được sử dụng để giải mã ở vòng cuối cùng, còn lệnh AESDEC được sử dụng để giải mã (lần lượt) ở tất cả các vòng còn lại. Ví dụ, trong AES-128, một khối dữ liệu phải được giải mã qua 10 vòng và có thể được thực hiện bằng việc sử dụng các câu lệnh trên như sau:
Như vậy, có thể thấy rằng việc sử dụng tập lệnh AES-NI sẽ giúp cho việc cài đặt thuật toán AES trở nên đơn giản. Người lập trình sẽ không phải quan tâm đến các biến đổi chi tiết bên trong thủ tục tạo khóa vòng, cũng không phải quan tâm đến các thao tác SubBytes, ShiftRowKey, MixColumn – là những thao tác mà có thể khiến người lập trình gặp khó khăn khi cài đặt bằng các lệnh hợp ngữ thông thường. Cần lưu ý rằng tập lệnh AES-NI không phải là một nhóm hàm của một thư viện lập trình nào đó, mà là những câu lệnh hợp ngữ đặc biệt của vi xử lý Intel, vì thế sẽ mang lại tốc độ tính toán tốt hơn.

Hiệu quả sử dụng AES-NI
Kết quả khảo sát của các chuyên gia đã chỉ ra rằng, việc sử dụng AES-NI sẽ làm tăng đáng kể tốc độ mã hóa và giải mã bằng AES. Đối với chế độ hoạt động không song song của AES như quá trình mã hóa trong chế độ CBC thì  hiệu suất khi sử dụng AES-NI có thể tăng 2 đến 3 lần so với cài đặt thông thường. Còn đối với chế độ song song như quá trình giải mã trong chế độ CBC và CTR, AES-NI có thể tăng tốc 10 lần so với cài đặt thông thường.

Hình 2. So sánh tốc độ mã hóa/giải mã cho hai trường hợp là  có sử dụng và không sử dụng AES-NI
Để thấy rõ được hiệu năng của AES-NI người ta sử dụng công cụ TrueCrypt để mã hóa và giải mã lần lượt các khối dữ liệu có kích thước khác nhau (50MB, 100MB, 200MB, 500MB, 1GB) khi sử dụng và không sử dụng AES-NI.
Bên cạnh việc cải thiện đáng kể tốc độ tính toán thì các chuyên gia cũng cho rằng AES-NI sẽ giúp cho việc cài đặt AES trở nên an toàn hơn, cụ thể là chống lại được tấn công kênh kề (side channel attack).
Vì những lợi ích mà AES-NI mang lại, hiện nay đã có nhiều sản phẩm phần mềm có sử dụng mật mã và nhiều thư viện lập trình hỗ trợ tập lệnh này. Trong số các sản phẩm phần mềm như thế có thể kể đến 7-Zip 9.1, BitLocker, BestCrypt, Open SSL, Oracle Database, PGP, TrueCrypt. Còn các thư viện lập trình thì bao gồm: Cryptography API Next Generation, .NET Framework, Crypto++ 5.6.1, CyaSSL, Java 7 HotSpot. Các chương trình và thư viện trên trước hết sẽ kiểm tra sự hỗ trợ tập lệnh AES-NI trên vi xử lý của máy thực thi chương trình. Nếu vi xử lý có hỗ trợ AES-NI thì các lệnh đó sẽ được sử dụng để thực thi thuật toán, còn nếu không thì sử dụng các lệnh thông thường.
Thực tế cho thấy tập lệnh AES-NI của vi xử lý Intel đã giúp tăng tốc đáng kể hoạt động của hệ mật AES. Tuy nhiên, đối với những người quan tâm đến vấn đề an toàn thông tin thì tốc độ là chưa đủ. Cần phải đảm bảo rằng trong tập lệnh đó không có bẫy nào được đặt vào nhằm làm giảm độ an toàn của hệ mật, giúp cho những tổ chức nhất định có thể truy cập được dữ liệu đã mã hóa của người dùng. Hiện vẫn chưa có nghiên cứu nào được công bố liên quan đến vấn đề này.