Mã hóa truyền tải trong mạng riêng ảo đòi hỏi các thuật toán đối xứng phải kết hợp được tốc độ xử lý gói tin cao với khả năng phòng vệ kiên cố trước các đòn tấn công kênh phụ vi kiến trúc. Trong nhiều năm, chuẩn mã hóa nâng cao ở chế độ Galois/Counter (AES-GCM) là lựa chọn mặc định trên các giao thức doanh nghiệp như IPsec và OpenVPN. Tuy nhiên, AES-GCM bộc lộ những hạn chế lớn về hiệu năng và rủi ro an toàn trên các nền tảng phần cứng thiếu tập lệnh chuyên dụng.

Khi các triển khai phần mềm tính toán các vòng lặp AES trên router nhúng, vi xử lý di động hoặc thiết bị IoT không có phần cứng tăng tốc AES-NI hay ARMv8 Crypto, chúng phải dựa vào các bảng tra cứu tính sẵn trong bộ nhớ (S-box). Việc truy xuất bộ nhớ này tạo ra sự biến thiên thời gian, khiến khóa bí mật dễ bị rò rỉ qua các cuộc tấn công xung đột bộ nhớ đệm. Thêm vào đó, phép nhân GHASH trên trường Galois $\mathbb{F}_{2^{128}}$ tiêu tốn rất nhiều chu kỳ CPU nếu thiếu khối nhân không nhớ (PCLMULQDQ).

WireGuard đã giải quyết triệt để sự phụ thuộc phần cứng này bằng cách chuẩn hóa duy nhất trên ChaCha20-Poly1305 AEAD (Mã hóa xác thực có dữ liệu liên kết), được quy định trong RFC 8439. Thông qua cấu trúc cộng-xoay-XOR (ARX) và cơ chế kẹp khóa toán học, ChaCha20-Poly1305 mang lại hiệu năng hằng số thời gian đồng nhất trên mọi kiến trúc vi xử lý.

Bối cảnh mật mã học vượt ra ngoài phần cứng AES

Để hiểu lý do các giao thức VPN hiện đại chuyển hướng khỏi AES-GCM trên các thiết bị đa dạng, hãy xem xét cơ chế thực thi của mật mã khối. AES hoạt động dựa trên mạng lưới thay thế - hoán vị. Bước thay thế phi tuyến tính (SubBytes) ánh xạ các byte đầu vào 8-bit qua phép biến đổi toán học gọi là Rijndael S-box.

Trong phần mềm tối ưu hiệu năng không có tập lệnh phần cứng, các kỹ sư thường biên dịch trước các phép biến đổi này thành bốn bảng tra cứu dung lượng 1 KB (Te0, Te1, Te2, Te3):

// Hàm vòng lặp AES phần mềm sử dụng bảng tra cứu S-box
state[0] = Te0[(s0 >> 24)       ] ^ Te1[(s1 >> 16) & 0xff] ^ 
           Te2[(s2 >>  8) & 0xff] ^ Te3[(s3      ) & 0xff] ^ rk[0];

Do các địa chỉ bộ nhớ được truy xuất trong Te0 đến Te3 phụ thuộc trực tiếp vào các byte của khóa bí mật và dữ liệu thô, chúng tạo ra các dấu vết truy cập bộ nhớ vi kiến trúc riêng biệt. Một tiến trình độc hại chạy cùng trên CPU có thể theo dõi thời gian nạp và đẩy dòng bộ nhớ đệm để khôi phục khóa riêng tư.

Ngược lại, ChaCha20 loại bỏ hoàn toàn các bảng tra cứu bộ nhớ. Nó vận hành như một mật mã dòng được điều khiển bởi cấu trúc đại số thuần túy ARX: Phép cộng modulo $2^{32}$ (Addition), phép xoay bit cố định (Rotation), và phép toán bitwise XOR. Mọi lệnh ARX đều hoàn thành trong số chu kỳ xung nhịp cố định trên các bộ số học logic (ALU) thông thường, giúp thuật toán miễn nhiễm tự nhiên trước các đòn tấn công kênh phụ định thời qua bộ nhớ đệm.

Triết lý ARX và ma trận trạng thái 4x4 của ChaCha20

Được thiết kế bởi Daniel J. Bernstein, ChaCha20 hoạt động trên trạng thái nội bộ 512-bit biểu diễn dưới dạng ma trận 4x4 gồm mười sáu từ 32-bit:

+---------------+---------------+---------------+---------------+
|  Constant 0   |  Constant 1   |  Constant 2   |  Constant 3   |
|  0x61707865   |  0x3320646e   |  0x79622d32   |  0x6b206574   |
+---------------+---------------+---------------+---------------+
|  Từ khóa 0    |  Từ khóa 1    |  Từ khóa 2    |  Từ khóa 3    |
+---------------+---------------+---------------+---------------+
|  Từ khóa 4    |  Từ khóa 5    |  Từ khóa 6    |  Từ khóa 7    |
+---------------+---------------+---------------+---------------+
| Bộ đếm khối   |    Nonce 0    |    Nonce 1    |    Nonce 2    |
+---------------+---------------+---------------+---------------+

Cấu trúc ma trận bảo đảm tính chặt chẽ mật mã:

  • Từ 0–3: Hằng số 128-bit cố định "expand 32-byte k", bảo đảm trạng thái ban đầu không bao giờ bằng 0 và ngăn chặn tấn công trượt.
  • Từ 4–11: Khóa phiên đối xứng 256-bit.
  • Từ 12: Bộ đếm khối 32-bit, tự động tăng sau mỗi khối dòng khóa 64-byte.
  • Từ 13–15: Số ngẫu nhiên sử dụng một lần (nonce) 96-bit.

Quá trình biến đổi trạng thái dựa trên hàm một phần tư vòng lặp QR(a, b, c, d) hòa trộn bốn từ qua bốn bước đại số:

// Hàm một phần tư vòng lặp ChaCha20 Quarter-Round
#define ROTL32(v, n) (((v) << (n)) | ((v) >> (32 - (n))))
#define QR(a, b, c, d) { \
    a += b; d ^= a; d = ROTL32(d, 16); \
    c += d; b ^= c; b = ROTL32(d, 12); \
    a += b; d ^= a; d = ROTL32(d,  8); \
    c += d; b ^= c; b = ROTL32(d,  7); \
}

Một chu trình ChaCha20 hoàn chỉnh thực thi 20 vòng lặp (10 vòng lặp theo cột xen kẽ với 10 vòng lặp theo đường chéo). Sau 20 vòng lặp, ma trận kết quả được cộng theo từng từ với ma trận khởi tạo ban đầu, rồi thực hiện phép XOR với 64 byte dữ liệu thô.

Do hàm QR chỉ tương tác trực tiếp trên các thanh ghi CPU và cổng ALU cơ bản, mã nguồn không có lệnh rẽ nhánh phụ thuộc dữ liệu, không truy xuất bộ nhớ và không phát sinh dao động độ trễ.

Mã xác thực một lần Poly1305 và cơ chế kẹp khóa

Tính bảo mật thông tin đơn thuần là chưa đủ trong thiết kế VPN. Nếu thiếu xác thực toàn vẹn, kẻ tấn công có thể chỉnh sửa gói tin mã hóa trên đường truyền, lật bit dữ liệu hoặc chèn các tải trọng độc hại. ChaCha20 kết hợp chặt chẽ với mã xác thực thông điệp Poly1305 để tạo thành hệ mã hóa AEAD hoàn chỉnh.

Poly1305 là bộ xác thực đa thức Carter-Wegman tính toán trên trường số nguyên tố $\mathbb{F}_{2^{130}-5}$. Để xác thực một gói tin mã hóa, thông điệp được chia thành các khối 16-byte, mỗi khối đóng vai trò là một hệ số đa thức:

$$A(r) = \left( \sum_{i=1}^{L} c_i \cdot r^{L-i+1} \right) \pmod{2^{130}-5} + s \pmod{2^{128}}$$

Cặp khóa xác thực dùng một lần $(r, s)$ 256-bit được sinh ra một cách xác định từ chính khối 64-byte đầu tiên (bộ đếm khối 0) do ChaCha20 tạo ra cho riêng gói tin đó:

  • Từ 0–3 cung cấp khóa đánh giá đa thức $r$ 128-bit.
  • Từ 4–7 cung cấp khóa đệm bảo mật $s$ 128-bit.

Để ngăn chặn hiện tượng tràn số nhớ lan truyền không kiểm soát giữa các thanh ghi khi nhân đa thức nhiều phần tử, khóa đánh giá $r$ được kẹp bit (clamping) trước khi tính toán:

// Thao tác kẹp khóa Poly1305 theo chuẩn RFC 8439
r[3] &= 15;  r[7] &= 15;  r[11] &= 15; r[15] &= 15;
r[4] &= 252; r[8] &= 252; r[12] &= 252;

Thao tác kẹp xóa sạch 22 bit cụ thể trong khóa 16-byte $r$. Ràng buộc toán học này giới hạn độ lớn của các tích trung gian sao cho $r < 2^{124}$. Nhờ đó, các thanh ghi ALU 32-bit và 64-bit có thể thực thi phép rút gọn modulo bằng chuỗi lệnh dịch bit và cộng nhanh mà không gây tràn số nhớ.

Cấu trúc khung AEAD của WireGuard so với chuẩn RFC 8439

Dù RFC 8439 định nghĩa một khuôn mẫu AEAD tổng quát cho các giao thức mạng, WireGuard đã tinh chỉnh cấu trúc này nhằm tối ưu hóa hiệu suất đường hầm:

Khuôn mẫu RFC 8439:    [ Bộ đếm 32-bit ] [ Nonce ngẫu nhiên 96-bit ] -> Xác thực AAD + Bản mã
Khuôn mẫu WireGuard:   [ Đệm 32-bit số 0 ] [ Bộ đếm gói tin 64-bit ] -> Bộ đếm gửi rõ trong tiêu đề

Trong giao thức WireGuard:

  1. Bộ đếm truyền tải 64-bit: Mỗi tiêu đề gói tin mang một giá trị bộ đếm 64-bit không mã hóa (receiver_index đi kèm counter). Giá trị này bắt đầu từ 0 khi thiết lập phiên và tăng tuần tự cho từng gói tin được phát đi.
  2. Tạo Nonce 96-bit: Nonce 96-bit cần cho ChaCha20 được tạo bằng cách đặt 32 bit số 0 ở phần trọng số cao, nối tiếp bởi bộ đếm 64-bit theo định dạng little-endian.
  3. Giới hạn đổi khóa nghiêm ngặt: Nếu một khóa phiên mã hóa hai gói tin khác nhau bằng cùng một nonce, tính an toàn của Poly1305 sẽ sụp đổ, làm lộ khóa $r$ qua phép trừ đa thức. Để ngăn chặn điều này, WireGuard bắt buộc tái thương lượng khóa phiên sau $2^{60}$ gói tin hoặc sau 120 giây, loại bỏ triệt để nguy cơ tái sử dụng nonce.

Bên cạnh đó, WireGuard không cần chèn thêm dữ liệu xác thực bổ sung (AAD) trong các gói tin dữ liệu thông thường vì thẻ xác thực Poly1305 16-byte đã bảo vệ trực tiếp tải trọng, còn chỉ số nhận gói tin được xác minh thông qua bảng Cryptokey Routing.

Tăng tốc SIMD: AVX2, AVX-512 và ARM NEON

Một ưu điểm kiến trúc nổi bật của ChaCha20 là khả năng tính toán song song tự nhiên. Khác với chế độ liên kết khối mã hóa (CBC) vốn đòi hỏi bản mã của khối trước để mã hóa khối sau, các khối dòng khóa ChaCha20 chỉ phụ thuộc vào khóa ban đầu, nonce và giá trị của bộ đếm khối.

Đặc tính này cho phép triển khai tối ưu trên các tập lệnh vectơ phần cứng:

  • ARM NEON: Trên chip di động, các thanh ghi NEON 128-bit tính toán hai hàm một phần tư vòng lặp song song cùng lúc.
  • x86_64 AVX2: Các thanh ghi vectơ 256-bit xử lý đồng thời bốn khối 64-byte hoàn chỉnh, tạo ra 256 byte dòng khóa trong mỗi chu kỳ.
  • x86_64 AVX-512: Thanh ghi 512-bit xử lý song song tám khối cùng lúc, sản sinh 512 byte dòng khóa mỗi chu kỳ.

Vì các cổng ALU vectơ thực thi phép xoay bit và phép cộng với độ trễ cố định, các triển khai SIMD song song duy trì tính kháng kênh phụ tuyệt đối trong khi đạt tốc độ xử lý vượt mức 3 GB/s trên mỗi nhân CPU.

Quy trình AEAD và phân phối đa nhân trong RiceGuard

Trong môi trường mạng doanh nghiệp tải cao, RiceGuard mở rộng cơ chế ChaCha20-Poly1305 thông qua kiến trúc xử lý tối ưu:

  1. Điều phối đa nhân song song: RiceGuard tích hợp với hạ tầng mã hóa song song trong nhân Linux (padata), phân bổ các luồng gói tin đến qua tất cả các nhân CPU trước khi sắp xếp lại theo đúng thứ tự chuyển giao cho ngăn xếp mạng.
  2. Kiểm tra tính xác thực hằng số thời gian: Trong quá trình giải mã gói tin, thẻ xác thực Poly1305 được đối chiếu bằng hàm so sánh bộ nhớ hằng số thời gian (crypto_memneq). Nếu thẻ xác thực không hợp lệ, gói tin bị hủy ngay lập tức trước khi chạm vào bộ đệm dữ liệu thô.
  3. Xóa bộ nhớ khóa tức thì: Các khóa phụ tạm thời ($r, s$) được làm sạch khỏi bộ nhớ đệm CPU bằng lệnh memzero_explicit ngay sau khi hoàn tất xác thực.

Nhờ cấu trúc ARX chuẩn mực, khả năng thực thi không nhánh và kỹ thuật kẹp khóa chặt chẽ, ChaCha20-Poly1305 cung cấp cho VPN một động cơ mã hóa kháng kênh phụ toàn diện và đạt hiệu năng tối đa trên mọi thế hệ phần cứng.

Tải VPNRice