Thứ Sáu, 25 tháng 10, 2019

[AES] Bài 7 - Lõi IP AES128 hỗ trợ chế độ mã hóa ECB, CBC, CFB, OFB và CTR

Bài viết này mô tả về thiết kế của lõi IP AES128 hỗ trợ 5 chế độ mã hóa thông dụng là ECB, CBC, CFB, OFB và CTR. Nội dung bài viết sẽ trình bày về đặc điểm, chức năng, cách thiết kế và chi tiết cấu tạo của lõi IP. Source code của lõi IP có thể được tải cuối bài viết kèm các testcase cơ bản.
Trước khi đọc bài này, các bạn cần tham khảo lại các bài viết trước vì nhiều khái niệm sẽ không được trình bày lại. Bên cạnh đó, bài viết này sẽ kế thừa thiết kế và RTL code của các bài viết trước. Danh sách các bài viết trước gồm:
1) Đặc điểm chức năng
AES128 là lõi IP hỗ trợ các đặc điểm sau đây:
  • Tương thích chuẩn AES-128, FIPS 197
  • Hỗ trợ khóa mã độ dài 128 bit
  • Hỗ trợ các chế độ mã hóa được mô tả trong tài liệu NIST 800-38A:
    • ECB – Electronic Codebook
    • CBC – Cipher Block Chaining
    • CFB – Cipher Feedback
      • 1 bit CFB
      • 2 bit CFB
      • 4 bit CFB
      • 8 bit CFB
      • 16 bit CFB
      • 32 bit CFB
      • 64 bit CFB
      • 128 bit CFB
  • OFB – Output Feedback
  • CTR – Counter
  • Không hỗ trợ bộ tạo vector khởi tạo (IV)
  • Không hỗ trợ sẵn counter cho chế độ CTR
2) Giao tiếp của lõi IP AES128
Hình 1: Sơ đồ tín hiệu giao tiếp của AES128
TT
Tên
Chiều
Mô tả
1
clk
Ngõ vào
Xung clock đồng bộ.
2
rst_n
Ngõ vào
Reset bất đồng bộ.
Tích cực mức thấp
3
cipher_en
Ngõ vào
Cho phép mã hóa một khối dữ liệu.
Tích cực 1 chu kỳ xung clock clk.
4
decipher_en
Ngõ vào
Cho phép giải mã một khối dữ liệu.
Tích cực 1 chu kỳ xung clock clk.
5
chain_en
Ngõ vào
Cho phép mã hóa/giải mã liên tục một chuỗi dữ liệu. Một chuỗi dữ liệu gồm nhiều khối dữ liệu.
Tích cực trong suốt quá trình xử lý đa khối, một chuỗi dữ liệu đang được xử lý.
Sử dụng kết hợp với cipher_en và decipher_en trong các chế độ CBC, CFB và OFB.
6
data_in[127:0]
Ngõ vào
Khối dữ liệu cần mã hóa hoặc giải mã.
7
key[127:0]
Ngõ vào
Khóa mã dùng cho quá trình mã hóa hoạc giải mã.
8
mode[3:0]
Ngõ vào
Chế độ mã hóa:
0000 = ECB
0001 = CBC
0010 = CFB
0011 = OFB
0100 = CTR
0101 đến 1111 = Không sử dụng
9
init_vector[127:0]
Ngõ vào
Vector khởi tạo được dùng trong các chế độ CBC, CFB và OFB.
Giá trị counter được dùng trong chế độ CTR.
10
segment_len[15:0]
Ngõ vào
Số bit của một đoạn dữ liệu.
Giá trị này dùng trong chế độ CFB, ứng với ký hiệu s trong tài liệu NIST 800-38A.
11
data_out[127:0]
Ngõ ra
Khối dữ liệu đầu ra sau mỗi lần mã hóa/giải mã.
Giá trị của tín hiệu này chỉ hợp lệ khi ready=1.
12
ready
Ngõ ra
Báo hiệu lõi IP AES128 trong trạng thái sẵn sàng thực hiện một xử lý mã hóa/giải mã dữ liệu mới.
1 = giá trị ngõ ra của AES128 là hợp lệ và sẵn sàng thực hiện quá trình mã hóa/giải mã tiếp theo
0 = giá trị ngõ ra của AES128 là không hợp lệ và AES128 đang bận.

Chú ý, cipher_en decipher_en không được phép cùng bằng 1. Tại một thời điểm, chỉ một trong hai tín hiệu này được phép tích cực để yêu cầu AES128 thực thi mã hóa hoặc giải mã. Việc tích cực cả hai tín hiệu cùng lúc sẽ làm AES128 hoạt động không đúng với chức năng mong muốn và cho kết quả không xác định được.
3) Sơ đồ khối
Hình 2: Sơ đồ khối lõi IP AES128
Lõi IP AES128 gồm các khối chức năng sau:
  • control logic: các logic nằm ở Top module được dùng để điều khiển lỗi mã hóa và lõi giải mã.
  • aes128_cipher_core: Khối thực thi quá trình mã hóa hay còn gọi là quá trình mã hóa thuận. Khối này còn làm nhiệm vụ tạo ra khóa vòng thứ 10 cho khối thực thi giải mã.
  • aes128_cipher_inv_core: Khối thực thi quá trình giải mã hay còn gọi là quá trình mã hóa nghịch.
4) Mô tả hoạt động
4.1) Chuỗi dữ liệu và khối dữ liệu
Chuỗi dữ liệu (data stream) gồm nhiều khối dữ liệu liên quan đến nhau.
Khối dữ liệu (data block) gồm 128 bit. Trong chế độ CFB, tùy cấu hình, có thể chỉ một phần khối dữ liệu là các bit MSB với độ dài s bit, được xử lý.
Hình 3: Chuỗi dữ liệu và khối dữ liệu
4.2) Chế độ xử lý đơn khối (chain_en=0)
Xử lý đơn khối là quá trình mã hóa/giải mã từng khối dữ liệu độc lập. Quá trình xử lý của khối sau không phụ thuộc vào kết quả của quá trình xử lý của khối trước đó. 
Xử lý đơn khối sử dụng trong các trường hợp sau: 
  • Chế độ ECB 
  • Chế độ CTR 
  • Chế độ CBC, CFB và OFB nếu độ dài một chuỗi dữ liệu nhỏ hơn hoặc bằng độ dài tiêu chuẩn của một khối dữ liệu. Nghĩa là độ dài chuỗi dữ liệu nhỏ hơn hoặc bằng 128 bit.
Trong chế độ xử lý này, chain_en luôn được lái mức thấp, logic 0.
4.3) Chế độ xử lý đa khối (chain_en=1)
Xử lý đa khối là quá trình mã hóa/giải mã một chuỗi dữ liệu có độ dài lớn hơn 128 bit trong các chế độ sau: 
  • Chế độ CBC
  • Chế độ CFB
  • Chế độ OFB
Trong chế độ xử lý này, chain_en luôn được lái mức cao, logic 1, trong suốt quá trình các khối dữ liệu trong chuỗi được xử lý. chain_en chỉ có thể được lái mức thấp, logic 0, khi tín hiệu ready=1 ở khối dữ liệu cuối cùng của chuỗi dữ liệu.
4.4) Quá trình mã hóa/giải mã một khối dữ liệu
Quá trình thực thi mã hóa/giải mã một khối dữ liệu như sau: 
1. RESET: Quá trình khởi tạo trạng thái lõi IP AES128 về trạng thái mặc định. Quá trình này xảy ra khi rst_n=0. AES128 phải được reset trước khi hoạt động. 
2. IDLE: Trạng thái AES128 rảnh. Trạng thái này tồn tại sau khi AES128 được reset hoặc sau khi thực thi xong quá trình mã hóa/giải mã một khối dữ liệu. Tín hiệu ready luôn bằng 1 trong suốt trạng thái này. Trong trạng thái này, các tín hiệu điều khiển phải được lái như sau: 
  • cipher_en = 0
  • decipher_en = 0
  • chain_en = 0 sau khi reset hoặc chuyển đổi giữa hai lần xử lý chuỗi dữ liệu
  • chain_en = 1 khi đang trong quá trình xử lý chuỗi dữ liệu gồm nhiều khối dữ liệu.
3. START: Trạng thái bắt đầu mã hóa/giải mã. Trạng thái này xảy ra khi cipher_en=1, khởi động mã hóa, hoặc decipher_en=1, khởi động giải mã. cipher_en decipher_en không được phép cùng tích cực mức 1. Hai tín hiệu này chỉ được tích cực trong 1 chu kỳ xung clock clk
  • chain_en = 0 nếu xử lý đơn khối 
  • chain_en = 1 nếu xử lý đa khối 
  • Các tín hiệu điều khiển khác phải có giá trị hợp lệ. Tín hiệu không sử dụng phải lái mức logic 0. 
4. BUSY: Trạng thái hoạt động của AES128. Tín hiệu ready luôn bằng 0 trong suốt quá trình hoạt động. cipher_en decipher_en không được phép tích cực mức 1 trong suốt trạng thái BUSY, ready=0
  • Giá trị các tín hiệu điều khiển không được phép thay đổi giá trị, chúng phải giữ cố định cho đến khi ready=1
5. Trạng thái IDLE sau một quá trình mã hóa/giải mã: Trạng thái này luôn tồn tại sau mỗi quá trình mã hóa/giải mã một khối dữ liệu. Nghĩa là nó phải tồn tại ít nhất 1 chu kỳ xung clock clk
6. START: Bắt đầu một quá trình mã hóa/giải mã cho khối dữ liệu mới.
Hình 4: Waveform minh hóa quá trình mã hóa/giải mã từng khối dữ liệu
4.5) Quá trình xử lý đơn khối và đa khối
Đối với xử lý đa khối:
  • chain_en phải luôn giữ tích cực, mức logic 1 cho đến khi khối dữ liệu cuối dùng trong chuối dữ liệu đã xử lý xong, ready=1.
  • chain_en chỉ lái bằng 0 giữa hai lần xử lý đa khối.
Đối với xử lý đơn khối, chain_en luôn lái mức 0.
Khi chuyển đổi giữa một quá trình mã hóa và giải mã, chain_en phải lái mức 0. Nghĩa là, sau khi một quá trình mã hóa hoàn thành, chain_en phải bằng 0 trước khi bắt đầu một quá trình giải mã tiếp theo và ngược lại.
Hình 5: Quá trình xử lý đa khối (chain_en=1)
5) Phương pháp phân tích thiết kế
Phương pháp thiết kế được áp dụng là top-down, phân tích từ tổng quan đến chi tiết. Thiết kế sẽ được phân tích từ mức tổng quát, từ top module, đến mức chi tiết hóa bởi những phần tử cơ bản. Phần tử cơ bản là phần tử mà người mô tả RTL có thể hiểu và mô hình hóa bằng ngôn ngữ mô tả phần cứng. Với thiết kế số, phần tử cơ bản là các cổng logic, Flip-Flop, latch, FSM, …
Chi tiết về phương pháp thiết kế đã được trình bày chi tiết hơn trong các bài viết về hướng dẫn phân tích thiết kế lõi IP step-by-step:
Hình 6: Minh họa phương pháp thiết kế top-down
6) Phân tích tổng quan lõi IP AES128
Lõi IP này sẽ tích hợp hai thiết kế có sẵn là: 
  • Bộ mã hóa AES128, module aes128_cipher_top, là phần thực thi chức năng CIPHk() trong chế độ mã hóa.
  • Bộ giải mã AES128, module aes128_cipher_inv_top, là phần thực thi chức năng CIPH-1k() trong chế độ giải mã.
Hình 7: Minh họa vị trí của bộ giải mã và mã hóa trong chế độ ECB
Như vậy, thành phần thực thi thuật toán mã hóa khối AES128 đã có sẵn. Đây là một thiết kế mà lõi chức năng chính (core function) đã có sẵn nên phần logic thêm vào có mục đích chính là điều khiển chính xác hoạt động của lõi chức năng này. Phần logic này gọi là “control logic” như đã thể hiện trong sơ đồ khối chức năng AES128. “control logic” sẽ tạo ra các tín hiệu nối với các chân của hai module có sẵn để thực hiện 2 nhiệm vụ:
  • Nhận tín hiệu điều khiển trên ngõ vào của AES128 và chuyển đổi thành tín hiệu điều khiển module mã hóa và giải mã
  • Giám sát ngõ ra hai module mã hóa và giải mã, để lấy đúng dữ liệu gửi đến ngõ ra AES128
Bước trên đây giúp chúng ta hình dung sơ đồ chức năng của lõi IP AES128. Tiếp theo, chúng ta sẽ phân tích các tín hiệu sẽ kết nối với khối mã hóa và khối giải mã. Phân tích này là bước quan trọng giúp chúng ta hoàn thiện kết nối trong mức TOP và làm rõ hơn chức năng của “control logic”.
7) Phân tích kết nối lõi mã hóa (mã hóa thuận)
Lõi mã hóa được sử dụng lại thiết kế đã mô tả trong Bài 3 - Thiết kế bộ mã hóa AES-128. 
Chân clk_sys sẽ nối với clk
Chân rst_n sẽ nối với rst_n
Chân cipher_key[127:0] sẽ nối với key[127:0]
Chân plain_text[127:0] sẽ nối đến một tín hiệu tên cipher_input_block[127:0], một tín hiệu chưa xác định logic cụ thể. Nó không thể nối trực tiếp với data_in[127:0] vì với mỗi chế độ mã hóa khác nhau thì dữ liệu ngõ vào để mã hóa khác nhau. Ví dụ:
  • ECB: lấy từ data_in
  • CBC: lấy từ kết quả của một phép XOR
Chân cipher_en sẽ nối đến một tín hiệu tên start_process, một tín hiệu chưa xác định logic cụ thể. Nó không thể nối trực tiếp với cipher_en của module TOP vì khối này phải được thực thi trong cả quá trình mã hóa và giải mã. Với quá trình giải mã, khối này có nhiệm vụ tính khóa vòng thứ 10 và cung cấp giá trị này cho khối mã hóa nghịch.
Chân cipher_text[127:0] nối với cipher_out[127:0]. Nó không thể nối trực tiếp đến data_out[127:0] ở moduel TOP vì tùy vào quy trình thực thi mà giá trị data_out có thể là plaintext hoặc ciphertext.
Chân cipher_ready nối với tín hiệu cipher_ready. Nó không nối với chân ready ở module TOP vì vì tùy vào quy trình thực thi là mã hóa hay giải mã mà thời điểm ready=1 sẽ khác nhau.
So với module mã hóa gốc, module mã hóa được sử dụng trong lõi IP này cần tạo thêm một tín hiệu tên cipher_key10[127:0] cấp cho khối mã hóa nghịch. Chúng ta có thể không nhận ra điều này khi phân tích kết nối cho khối mã hóa mà nó sẽ phát sinh khi phân tích kết nối cho khối mã hóa nghịch.
Hình 8: Kết nối của khối mã hóa trong module Top
Theo phân tích trên, một logic sẽ được thêm vào khối mã hóa để tạo ra khóa vòng thứ 10 cho khối giải mã hoạt động. Logic được thêm vào là một thanh ghi lưu lại khóa vòng thứ 10. Trong chế độ ECB và CBC, quá trình giải mã cần thực thi chức năng “mã hóa nghịch”. Chức năng này cần khóa vòng thứ 10 để biến đổi ngược từ ciphertext thành plaintext. Vì vậy, trước khi quá trình giải mã thực thi, quá trình mã hóa được khởi động để tính khóa vòng thứ 10 trước. Sau đó, quá trình mã hóa ngược mới được khởi động.
Hình 9: Sơ đồ khối của khối mã hóa thuận được thêm vào thanh ghi cipher_key10
8) Phân tích kết nối khối giải mã (mã hóa nghịch)
Lõi giải mã được sử dụng lại từ thiết kế đã mô tả trong Bài 4 - Thiết kế bộ giải mã AES-128
Chân clk_sys sẽ nối với clk
Chân rst_n sẽ nối với rst_n
Chân round_key_10[127:0] sẽ nối với cipher_key10[127:0]. Như đã trình bày trong phần phân tích kết nối cho khối mã hóa, khối giải mã cần giá trị của khóa vòng thứ 10 để hoạt động mà thông tin này chỉ có thể được cung cấp từ khối mã hóa nên tín hiệu này sẽ nối đến khỗi mã hóa.
cipher_text[127:0] sẽ nối với decipher_input_block[127:0]. một tín hiệu chưa xác định logic cụ thể. Nó không thể nối trực tiếp với data_in[127:0] vì với mỗi chế độ giải mã khác nhau thì dữ liệu ngõ vào để giải mã khác nhau.
Chân decipher_en sẽ nối với start_decipher, một tín hiệu chưa xác định logic cụ thể, vì khối này chỉ chạy sau khi việc tính khóa vòng thứ 10 đã hoàn thành.
Chân plain_text[127:0] sẽ nối với decipher_out[127:0], không nối trực tiếp với data_out của module TOP. Chân decipher_ready[127:0] sẽ nối với decipher_ready[127:0], không nối trực tiếp với ready của module TOP.
Hình 10: Kết nối của khối mã hóa nghịch trong module TOP
Dưới đây là sơ đồ khối của khối mã hóa nghịch với mục đích tham khảo chi tiết hơn khi cần.
Hình 11: Sơ đồ khối của khối giải mã
9) Phân tích kết nối của control logic
“control logic” không phải là một module riêng. Nó là một tập hợp các logic nằm trực tiếp trong module TOP. Tuy nhiên phân tích này giúp hình dung rõ các ngõ vào và ngõ ra của “control logic”.
Các tín hiệu kết nối với “control logic” đã được phân tích đầy đủ thông qua việc phân tích kết nối của hai khối mã hóa và giải mã. Cụ thể, kết nối của cụm logic này sẽ là các kết nối với module TOP và các kết nối với khối mã hóa và giải mã, ngoại trừ các tín hiệu nối trực tiếp từ module TOP đến khối mã hóa/giải mã và các tín hiệu nối giữa hai khối mã hóa/giải mã.
Hình 12: Kết nối của khối "control logic"
10) Phân tích chi tiết khối "control logic"
Sau khi các kết nối của module TOP đã hoàn chỉnh. Bước tiếp theo là phân tích chi tiết các mạch logic của “control logic”. Bước này sẽ hoàn thành ghi toàn bộ ngõ ra của “control logic” được tạo ra bằng cách tổ hợp các tín hiệu ngõ vào. 
10.1) start_process
Đây là tín hiệu khởi động khối mã hóa. Như đã trình bày, khối này sẽ hoạt động cả trong quá trình mã hóa và giải mã dữ liệu.
Hình 13: Mạch nguyên lý tín hiệu start_process
10.2) start_decipher
Tín hiệu này sẽ khởi động khối mã hóa nghịch. Khối này chỉ được khởi động khi đáp ứng đầy đủ các điều kiện sau: 
  • Chế độ hoạt động là ECB hoặc CBC. Chỉ hai chế độ này mới sử dụng khối mã hóa nghịch 
  • Chế độ giải mã được sử dụng. Chế độ giải mã hoạt động sau khi decipher_en=1
  • Hoạt động của khối mã hóa đã hoàn thành để sinh ra khóa vòng thứ 10.
Hình 14: Mạch nguyên lý của tín hiệu start_decipher

10.3) ready

Tín hiệu này báo hiệu một quá trình mã hóa hoặc giải mã đã hoàn thành. Nó sẽ bị xóa ngay khi bắt đầu một quá trình xử lý mới và được tích cực khi một quá trình mã hóa hoặc giải mã một khối dữ liệu kết thúc.
Hình 15: Mạch nguyên lý tín hiệu ready
Một quá trình mới bắt đầu khi tín hiệu start_process=1. Một quá trình mã hóa kết thúc khi decipher_mode=0 và tín hiệu end_cipher=1. Một quá trình giải mã kết thúc khi: 
  • Đối với chế độ ECB và CBC: end_decipher=1
  • Đối với các chế độ khác: end_cipher=1 vì các chế độ này dùng chính chức năng mã hóa để thực hiện quá trình giải mã.
10.4) cipher_input_block[127:0]
Tín hiệu này cung cấp dữ liệu đầu vào cho khối mã hóa. Giá trị của tín hiệu này phụ thuộc vào các điều kiện sau: 
  • first_block xác định đó có phải là bước thực thi đầu tiên hay không? Trong một số chế độ hoạt động, dữ liệu đầu vào (input block) của lần thực thi đầu tiên và các lần thực thi tiếp theo lấy từ hai nguồn khác nhau. Ví dụ, trong chế độ CBC: 
    • Lần thực thi đầu tiên, dữ liệu đầu vào là XOR của IV và plaintext 
    • Lần thực thi tiếp theo, dữ liệu đầu vào là XOR của khối ngõ ra (output block) và plaintext 
  • mode[3:0] mode_reg[3:0] xác định chế độ hoạt động. Các chế độ hoạt động khác nhau sẽ yêu cầu dữ liệu đầu vào khác nhau. Ví dụ, xét lần thực thi đầu tiên: 
    • Chế độ CBC, dữ liệu đầu vào là XOR của IV và plaintext 
    • Chế độ CFB, dữ liệu đầu vào là IV segment_len xác định cách ghép nối các bit dữ liệu trong chế độ CFB
Hình 16: Mạch nguyên lý tín hiệu output_block[127:0]
Mạch nguyên lý trên sử dụng cho cả lần thực thi mã hóa/giải mã đầu tiên và các lần thực thi tiếp theo trong xử lý đa khối. Vì vậy, trong một số chế độ hoạt động, cần các thanh ghi lưu lại giá trị của lần thực thi hiện tại để sử dụng cho lần thực thi tiếp theo. Các thanh ghi này là: 
  • start_reg[127:0] lưu thông tin bắt đầu của mỗi lần thực thi
  • end_reg[127:0] lưu thông tin kết thúc của một lần thực thi
Hình 17: Mạch nguyên lý thanh ghi start_reg
Hình 18: Mạch nguyên lý thanh ghi end_reg
Mạch trên có sử dụng dữ liệu lấy từ ngõ ra của khối mã hóa và khối mã hóa nghịch, gọi là output_block[127:0].
Hình 19: Mạch nguyên lý chọn dữ liệu từ ngõ ra khối mã hóa và khối mã hóa nghịch
10.5) decipher_input_block[127:0]
Tín hiệu này cung cấp dữ liệu đầu vào cho khối mã hóa nghịch. Giá trị của tín hiệu này phụ thuộc vào các điều kiện sau: 
  • first_block xác định đó có phải là bước thực thi đầu tiên hay không? Trong một số chế độ hoạt động, dữ liệu đầu vào (input block) của lần thực thi đầu tiên và các lần thực thi tiếp theo lấy từ hai nguồn khác nhau. Ví dụ, trong chế độ CFB: 
    • Lần thực thi đầu tiên, dữ liệu đầu vào là IV 
    • Lần thực thi tiếp theo, dữ liệu đầu vào là một chuỗi bit ghép giữa khối ngõ vào (input block) và ciphertext của lần giải mã trước đó. 
  • mode mode_reg xác định chế độ hoạt động. Các chế độ hoạt động khác nhau sẽ yêu cầu dữ liệu đầu vào khác nhau. Ví dụ, xét lần thực thi đầu tiên: 
    • Chế độ CBC, dữ liệu đầu vào là ciphertext
    • Chế độ CFB, dữ liệu đầu vào là IV
Hình 20: Mạch nguyên lý tín hiệu decipher_input_block
10.6) data_out[127:0]
Đây là ngõ ra chứa dữ liệu của một quá trình mã hóa hoặc giải mã khi ready=1. Dữ liệu ngõ ra được tổ hợp như thế nào phụ thuộc vào các yếu tố sau đây: 
  • decipher_mode xác định quy trình hiện tại là mã hóa hay giải mã 
  • mode_reg xác định chế độ hoạt động hiện tại 
  • end_cipher end_decipher xác định thời điểm cập nhật giá trị thanh ghi data_out
  • segment_len xác định số bit được XOR dùng trong chế độ CFB.
Hình 21: Mạch nguyên lý tín hiệu data_out
11) Mô phỏng cơ bản
Trong source code, tác giả cung cấp một số testcase đơn giản (simple testcase) để giúp kiểm tra nhanh hoạt động của các chế độ mã hóa. Danh sách testcase:
  • tb_aes128_ecb.sv - Kiểm tra chế độ mã hóa, giải mã ECB
  • tb_aes128_cbc.sv - Kiểm tra chế độ mã hóa, giải mã CBC
  • tb_aes128_cfb_cipher.sv - Kiểm tra chế độ mã hóa CFB
  • tb_aes128_cfb_decipher.sv - Kiểm tra chế độ giải mã CFB
  • tb_aes128_ofb.sv - Kiểm tra chế độ mã hóa, giải mã OFB
  • tb_aes128_ctr.sv - Kiểm tra chế độ mã hóa, giải mã CTR
Phần chức năng chính của các testcase này sẽ gồm nhiều đoạn code như sau:
    repeat (1) @ (posedge clk); 
cipher_en   = 1; 
decipher_en = 0; 
chain_en    = 1; 
data_in     = 128'h6bc1bee22e409f96e93d7e117393172a; 
key         = 128'h2b7e151628aed2a6abf7158809cf4f3c; 
mode        = 4'd1; 
init_vector = 128'h000102030405060708090a0b0c0d0e0f; 
segment_len = 4'd0; 
    repeat (1) @ (posedge clk);    cipher_en   = 0;    //
    @ (posedge ready);
    info_task();

if(data_out != 128'h7649abac8119b246cee98e9b12e9197d) begin 
fail_flag = 1; 
  $strobe ("----- FAIL");
$strobe ("  +++ Expected: 7649abac8119b246cee98e9b12e9197d");
  $strobe ("  +++ Actual:   %32h", data_out);
end 
else begin 
  $strobe ("----- PASS");
end
Bước 1, phần code tô màu xanh là phần khởi tạo một quy trình mã hóa (cipher_en=1) hoặc giải mã (decipher_en=1). Các tín hiệu điều khiển khác được cung cấp giá trị thích hợp để thiết lập chế độ và dữ liệu mong muốn.
Bước 2, phần code tô màu đỏ sẽ xóa tín hiệu cipher_en hoặc decipher_en về logic 0 sau một chu kỳ xung clock clk.
Bước 3, phần code tô màu hồng sẽ chờ tín hiệu ready tích cực để hiển thị các thông tin giúp trace hoặc debug khi cần thông qua task info_task().
Cuối cùng, ngõ ra data_out sẽ được so sánh với giá trị kiểm tra mong muốn để báo PASS hoặc FAIL cho từng khối dữ liệu được mã hóa hoặc giải mã. Nếu FAIL, cờ fail_flag sẽ được thiết lập mức 1. Cờ này sẽ dùng để báo kết quả cuối cùng.
Chú ý, các giá trị kiểm tra (test vector) và kết quả dùng để so sánh được lấy từ tài liệu tham khảo số 2.
Nếu không có bất cứ khối dữ liệu nào bị FAIL thì kết quả như hình sau:
Hình 22: Kết quả mô phỏng PASS cho chế độ CBC trên phần mềm QuestaSim
Một môi trường mô phỏng có khả năng test đầy đủ các trường hợp sẽ được nhóm verification của page xây dựng và công bố sau.
12) Tổng hợp trên Quartus II của Altera-Intel
Mục đích của bước này để kiểm tra khả năng tổng hợp của RTL code.
Hình 23: Kết quả tổng hợp trên FPGA Arria V

Tài liệu tham khảo:
1) FIPS 197; ADVANCED ENCRYPTION STANDARD (AES); 2001
2) NIST Special Publication 800-38A; Recommendation for Block Cipher Modes of Operation - Methods and Techniques; 2001.

Source code có thể tải:
Source code trên GitHub

Lịch sử cập nhật:
1) 2019.10.25 - Tạo lần đầu

1 bình luận: