Lưu ý
Mục đích của file này là để độc giả tiếng Việt có thể đọc và hiểu tài liệu nhân kernel dễ dàng hơn, không phải để tạo ra một nhánh tài liệu riêng. Nếu bạn có bất kỳ nhận xét hoặc cập nhật nào cho file này, vui lòng thử cập nhật file tiếng Anh gốc trước. Nếu bạn thấy có sự khác biệt giữa bản dịch và bản gốc, hoặc có vấn đề về bản dịch, vui lòng gửi góp ý hoặc patch cho người dịch của file này, hoặc nhờ người bảo trì và người review tài liệu tiếng Việt giúp đỡ.
- Bản gốc:
- Người dịch:
Google Translate (machine translation)
- Phiên bản gốc:
8541d8f725c6
Cảnh báo
Tài liệu này được dịch tự động bằng máy và chưa được review bởi người dịch. Nội dung có thể không chính xác hoặc khó hiểu ở một số chỗ. Khi có sự khác biệt với bản gốc, bản gốc luôn là chuẩn. Bản dịch chất lượng cao (được review) được đặt trong thư mục vi_VN/.
Phát triển thuật toán mật mã¶
Đăng ký và hủy đăng ký chuyển đổi¶
Có ba loại chức năng đăng ký riêng biệt trong Crypto API. Một được sử dụng để đăng ký một chuyển đổi mật mã chung, trong khi hai cái còn lại dành riêng cho các phép biến đổi HASH và NÉN. Chúng ta sẽ thảo luận về hai điều sau trong một chương riêng, ở đây chúng ta sẽ chỉ nhìn vào những cái chung chung.
Trước khi thảo luận về các chức năng đăng ký, cấu trúc dữ liệu cần
chứa đầy từng cấu trúc, struct crypto_alg, phải được xem xét -- xem bên dưới
để biết mô tả về cấu trúc dữ liệu này.
Các chức năng đăng ký chung có thể được tìm thấy trong include/linux/crypto.h và định nghĩa của chúng có thể được xem bên dưới. các hàm trước đăng ký một phép biến đổi duy nhất, trong khi hàm sau hoạt động trên một loạt các mô tả chuyển đổi. Cái sau rất hữu ích khi đăng ký các chuyển đổi hàng loạt, ví dụ như khi một trình điều khiển thực hiện nhiều phép biến đổi.
- int crypto_register_alg(struct crypto_alg *alg);
int crypto_register_algs(
struct crypto_alg*algs, int count);
Các đối tác của các chức năng đó được liệt kê dưới đây.
- void crypto_unregister_alg(struct crypto_alg *alg);
void crypto_unregister_algs(
struct crypto_alg*algs, int count);
Các hàm đăng ký trả về 0 nếu thành công hoặc có lỗi âm
giá trị khi thất bại. crypto_register_algs() chỉ thành công nếu nó
đăng ký thành công tất cả các thuật toán đã cho; nếu nó thất bại giữa chừng
qua, sau đó mọi thay đổi sẽ được khôi phục.
Chức năng hủy đăng ký luôn thành công nên không có giá trị trả về. Đừng cố hủy đăng ký các thuật toán không phù hợp hiện đã đăng ký.
Mật mã đối xứng một khối [CIPHER]¶
Ví dụ về các phép biến hình: aes, snake, ...
Phần này mô tả cách chuyển đổi đơn giản nhất triển khai, đó là loại CIPHER được sử dụng cho mật mã đối xứng. Loại CIPHER được sử dụng cho các phép biến đổi hoạt động trên chính xác một khối tại một thời điểm và không có sự phụ thuộc nào giữa các khối.
Thông tin đăng ký cụ thể¶
Việc đăng ký thuật toán [CIPHER] cụ thể trong cấu trúc đó trường crypto_alg .cra_type trống. .cra_u.cipher phải là điền vào các lệnh gọi lại thích hợp để thực hiện chuyển đổi này.
Xem cấu trúc cipher_alg bên dưới.
Định nghĩa mật mã Với struct cipher_alg¶
Cấu trúc cipher_alg xác định một mật mã khối đơn.
Dưới đây là sơ đồ về cách gọi các hàm này khi được vận hành từ
phần khác của hạt nhân. Lưu ý rằng lệnh gọi .cia_setkey() có thể xảy ra
trước hoặc sau khi bất kỳ sơ đồ nào trong số này xảy ra, nhưng không được xảy ra
trong bất kỳ thời điểm nào trong số này đang trên chuyến bay.
- KEY ---. PLAINTEXT ---.
v v
- .cia_setkey() -> .cia_encrypt()
‘-------> CIPHERTEXT
Xin lưu ý rằng mẫu trong đó .cia_setkey() được gọi nhiều lần
cũng hợp lệ:
- KEY1 --. PLAINTEXT1 --. KEY2 --. PLAINTEXT2 --.
v v v v
- .cia_setkey() -> .cia_encrypt() -> .cia_setkey() -> .cia_encrypt()
ZZ0000ZZ ‘---> CIPHERTEXT1 ‘---> CIPHERTEXT2
Mật mã nhiều khối¶
Ví dụ về các phép biến đổi: cbc(aes), chacha20, ...
Phần này mô tả việc chuyển đổi mật mã đa khối triển khai. Mật mã đa khối được sử dụng để chuyển đổi hoạt động trên danh sách phân tán dữ liệu được cung cấp cho quá trình chuyển đổi chức năng. Họ cũng xuất kết quả thành một danh sách phân tán dữ liệu.
Thông tin đăng ký cụ thể¶
Việc đăng ký các thuật toán mã hóa đa khối là một trong những các quy trình tiêu chuẩn trong toàn bộ mật mã API.
Lưu ý, nếu việc triển khai mật mã yêu cầu căn chỉnh dữ liệu phù hợp,
người gọi nên sử dụng các hàm của crypto_skcipher_alignmask() để
xác định mặt nạ căn chỉnh bộ nhớ. Mật mã hạt nhân API có thể
xử lý các yêu cầu không được căn chỉnh. Tuy nhiên, điều này ngụ ý thêm
chi phí chung vì mật mã hạt nhân API cần thực hiện việc sắp xếp lại
dữ liệu có thể ngụ ý di chuyển dữ liệu.
Định nghĩa mật mã Với struct skcipher_alg¶
Cấu trúc skcipher_alg định nghĩa một mật mã đa khối, hay nói chung hơn là một thuật toán mã hóa đối xứng bảo toàn độ dài.
Xử lý danh sách phân tán¶
Một số trình điều khiển sẽ muốn sử dụng Generic ScatterWalk trong trường hợp phần cứng cần được cung cấp các phần riêng biệt của danh sách phân tán chứa bản rõ và sẽ chứa bản mã. Hãy tham khảo tới giao diện ScatterWalk được cung cấp bởi nhân Linux phân tán / tập hợp thực hiện danh sách.
Băm [HASH]¶
Ví dụ về các phép biến đổi: crc32, md5, sha1, sha256,...
Đăng ký và hủy đăng ký chuyển đổi¶
Có nhiều cách để đăng ký chuyển đổi HASH, tùy thuộc vào liệu chuyển đổi có đồng bộ [SHASH] hay không đồng bộ [AHASH] và số lượng phép biến đổi HASH mà chúng tôi đang đăng ký. bạn có thể tìm thấy các nguyên mẫu được xác định trong include/crypto/internal/hash.h:
int crypto_register_ahash(struct ahash_alg *alg);
- int crypto_register_shash(struct shash_alg *alg);
int crypto_register_shashes(
struct shash_alg*algs, int count);
Các đối tác tương ứng để hủy đăng ký chuyển đổi HASH như sau:
void crypto_unregister_ahash(struct ahash_alg *alg);
Định nghĩa mật mã Với struct shash_alg và ahash_alg¶
Dưới đây là sơ đồ về cách gọi các hàm này khi được vận hành từ
phần khác của hạt nhân. Lưu ý rằng cuộc gọi .setkey() có thể xảy ra
trước hoặc sau khi bất kỳ sơ đồ nào trong số này xảy ra, nhưng không được xảy ra
trong bất kỳ thời điểm nào trong số này đang trên chuyến bay. Xin lưu ý rằng việc gọi .init()
ngay sau đó là .final() cũng là một kết quả hoàn toàn hợp lệ
sự biến đổi.
- Tôi) DATA -----------.
v
- .init() -> .update() -> .final() ! .update() có thể không được gọi
^ ZZ0000ZZ trong kịch bản này. ‘----’ ‘---> HASH
- DATA -------------.----------.
v v
- .init() -> .update() -> .finup() ! .update() có thể không được gọi
^ ZZ0000ZZ trong kịch bản này. ‘----’ ‘---> HASH
- DATA ----------.
v
- .digest() ! Toàn bộ quá trình được xử lý
- bằng lệnh gọi .digest().
‘---------------> HASH
Dưới đây là sơ đồ về cách gọi các hàm .export()/.import()
khi được sử dụng từ một phần khác của kernel.
- KEY--. DATA--.
v v ! .
update()có thể không được gọi- .setkey() -> .init() -> .update() -> .export() trong trường hợp này.
^ ZZ0000ZZ ‘------’ ‘--> PARTIAL_HASH
----------- những biến đổi khác xảy ra ở đây -----------
- PARTIAL_HASH--. DATA1--.
v v
- .import -> .update() -> .final() ! .update() có thể không được gọi
^ ZZ0000ZZ trong kịch bản này. ‘----’ ‘--> HASH1
- PARTIAL_HASH--. DATA2-.
v v
- .import -> .finup()
‘---------------> HASH2
Lưu ý rằng việc “từ bỏ” một đối tượng yêu cầu là hoàn toàn hợp pháp:
- gọi .init() và sau đó (nhiều lần) .update()
- _not_ gọi bất kỳ .final(), .finup() hoặc .export() nào tại bất kỳ thời điểm nào trong tương lai
Nói cách khác, việc triển khai nên lưu ý đến việc phân bổ và dọn dẹp tài nguyên.
Không có tài nguyên nào liên quan đến đối tượng yêu cầu sẽ được phân bổ sau cuộc gọi
thành .init() hoặc .update(), vì có thể không có cơ hội giải phóng chúng.
Thông số cụ thể của chuyển đổi HASH không đồng bộ¶
Một số trình điều khiển sẽ muốn sử dụng Generic ScatterWalk trong trường hợp việc triển khai cần được cung cấp các phần riêng biệt của danh sách phân tán chứa dữ liệu đầu vào.