Bài 8: Bảo mật firmware update trong bootloader trên microcontroller

Ở các bài trước, mình đã nói về bootloader, firmware update và fail-safe. Nhưng chỉ update được thôi thì chưa đủ. Nếu không chặn đúng từ đầu, thiết bị vẫn có thể nhận nhầm firmware giả, firmware bị sửa hoặc firmware cũ có lỗ hổng.

Trong bài này, mình đi vào phần bảo mật của firmware update trên MCU.

Trọng tâm là ai được phép update, bootloader kiểm tra application image như thế nào, key nằm ở đâu và vì sao anti-rollback, chain of trust hay certificate lại quan trọng.

Vì sao firmware update phải có bảo mật

Firmware update là cơ chế hợp lệ để thay đổi phần mềm của thiết bị. Nếu cơ chế này không được bảo vệ, attacker có thể lợi dụng nó để nạp firmware độc hại, hạ version về bản cũ có lỗ hổng hoặc giả mạo tool update.

Điểm cần tách rõ là fail-safe update không đồng nghĩa với secure update. Một hệ có thể rollback tốt khi update lỗi, nhưng vẫn không an toàn nếu nó chấp nhận firmware không đáng tin.

Những thứ cần bảo vệ trong update flow

Khi nói tới secure update, thường phải kiểm soát ít nhất các việc sau.

  • Ai được phép bắt đầu phiên update.
  • Application image nhận vào có đúng nguồn gốc hay không.
  • Dữ liệu có bị sửa trên đường truyền hay không.
  • Thiết bị có cho phép hạ về version cũ hay không.
  • Key, metadata và trạng thái boot có bị sửa trái phép hay không.

Phân biệt integrity, authenticity và authorization

Ba khái niệm này liên quan nhau nhưng không giống nhau.

Integrity là dữ liệu còn nguyên vẹn, không bị lỗi hoặc bị sửa ngoài ý muốn.

Authenticity là dữ liệu đúng là từ nguồn tin cậy.

Authorization là đúng người, đúng tool hoặc đúng thành phần được phép thực hiện update.

Ví dụ, CRC có thể giúp kiểm tra integrity, nhưng không chứng minh được authenticity. Một phiên update có thể có lớp bảo vệ ở mức giao tiếp, nhưng nếu bootloader không xác thực application image thì vẫn có rủi ro.

CRC, hash và chữ ký số

Đây là chỗ rất nhiều người hay lẫn.

CRC hoặc checksum chủ yếu dùng để phát hiện lỗi dữ liệu ngẫu nhiên. Nó hợp cho việc bắt lỗi truyền nhận hoặc lỗi lưu trữ đơn thuần.

Hash là giá trị băm của dữ liệu. Nếu dữ liệu thay đổi thì hash cũng đổi theo. Tuy nhiên, hash tự nó chưa chứng minh được ai là người tạo ra dữ liệu đó.

Digital signature, tức chữ ký số, mới là cơ chế để bootloader kiểm tra application image có thật sự do bên phát hành tin cậy ký ra hay không. Đây là điểm khác nhau quan trọng nhất giữa secure update và một bài kiểm tra CRC thông thường.

Nói ngắn gọn, CRC giúp phát hiện lỗi, hash giúp nhận biết dữ liệu đã đổi, còn chữ ký số giúp xác thực nguồn gốc của application image.

Public key và private key

Để verify chữ ký số, bootloader thường cần public key. Đây là khóa công khai, có thể nằm trong ROM, trong bootloader image hoặc trong vùng secure storage tùy thiết kế.

Ngược lại, private key là khóa bí mật dùng để ký firmware ở phía build server hoặc phía phát hành. Private key không được nằm trên thiết bị. Nếu private key lộ, attacker có thể tạo firmware giả nhưng vẫn vượt qua bước verify.

Public key dùng để verify chữ ký.

Private key dùng để tạo chữ ký.

Thiết bị chỉ nên có public key hoặc trust anchor, không nên có private key.

Xác thực trước khi cho phép update

Một số thiết bị cho phép bất kỳ ai đưa hệ thống vào update mode. Một số thiết bị khác chỉ cho update khi có tool service hợp lệ, challenge-response hoặc quyền riêng cho factory và đội bảo trì.

Ở đây có hai lớp cần tách rõ. Lớp thứ nhất là quyền bắt đầu phiên update. Lớp thứ hai là quyền cài application image. Một thiết kế chặt thường kiểm soát cả hai, chứ không chỉ một.

Xác thực application image

Sau khi nhận application image, bootloader cần verify image đó trước khi boot hoặc trước khi commit boot state. Việc verify này thường dựa trên chữ ký số và public key đã được tin sẵn trong thiết bị.

Điểm quan trọng là bootloader không nên tin vào metadata nằm trong application image mới nếu phần đó chưa được verify. Thứ duy nhất có thể tin từ đầu là trust anchor đã nằm trong root of trust của hệ thống.

Chain of trust và certificate

Chain of trust là chuỗi tin cậy từ phần gốc đã được tin sẵn cho tới application image cuối cùng. Với MCU, điểm gốc này thường là một public key, key hash hoặc trust anchor được ghim sẵn trong thiết bị.

Certificate là chứng chỉ số dùng để ràng buộc một public key với một thực thể tin cậy nào đó. Nếu bootloader hỗ trợ verify certificate chain, nó có thể linh hoạt hơn trong việc thay key hoặc phân quyền ký firmware.

Tuy nhiên, certificate chain không phải lúc nào cũng phù hợp với MCU nhỏ.

Nó làm logic verify nặng hơn, tốn RAM hơn và phức tạp hơn.

Vì vậy nhiều hệ MCU chọn cách ghim thẳng public key hoặc key hash thay vì kéo cả certificate chain vào bootloader.

Anti-rollback

Rollback để cứu máy khi update lỗi không giống với việc cho phép hạ về mọi version cũ. Một bản firmware cũ có thể vẫn chạy được, nhưng lại có lỗ hổng bảo mật đã biết.

Vì vậy nhiều hệ dùng security counter, version counter hoặc monotonic counter để chặn application image có version thấp hơn mức cho phép.

Đây là chỗ phải cân bằng giữa safety và security, vì đôi khi rollback là cần cho ổn định, nhưng rollback vô hạn lại tạo lỗ hổng.

Mã hóa đường truyền và mã hóa application image

Mã hóa đường truyền giúp giảm rủi ro bị nghe lén hoặc chèn dữ liệu trên kênh truyền. Nhưng encryption không thay thế authentication. Một image được mã hóa nhưng không được xác thực đúng vẫn có thể là image độc hại.

Cũng cần tách rõ mã hóa đường truyền với mã hóa application image lưu trong flash. Có hệ mã hóa application image để bảo vệ tài sản trí tuệ hoặc giảm rủi ro đọc trộm nội dung firmware. Dù vậy, việc mã hóa vẫn không thay cho bước verify nguồn gốc của image.

Quản lý key trong bootloader

Private key không được nằm trên thiết bị. Bootloader chỉ nên giữ public key, key hash hoặc trust anchor phục vụ việc verify.

Một điểm nữa là key rotation. Nếu sau này cần thay key, hệ thống phải có cách chuyển trust an toàn. Nếu không tính từ đầu, một khi key bị lộ thì toàn bộ thiết bị ngoài hiện trường sẽ rất khó xử lý.

Những lỗi thiết kế hay gặp

Một số lỗi rất hay gặp trong secure update trên MCU gồm các điểm sau.

  • Dùng CRC thay cho chữ ký số.
  • Verify image quá muộn, sau khi đã commit boot state.
  • Không có anti-rollback.
  • Mở update mode quá rộng mà không kiểm soát quyền.
  • Để trust anchor ở vùng dễ bị sửa.
  • Nhầm giữa secure update và secure boot.

Liên hệ giữa secure update và secure boot

Secure update bảo vệ lúc nhận và cài application image. Secure boot bảo vệ lúc thiết bị quyết định có boot image đó hay không. Hai phần này liên quan chặt nhưng không phải một.

Một thiết kế chặt thường kết hợp cả hai. Phần update chỉ nên nhận application image hợp lệ, còn phần boot phải đảm bảo chỉ application image hợp lệ mới được chạy.

Kết luận

Bảo mật firmware update trong bootloader là bài toán nhiều lớp: xác thực người hoặc tool update, xác thực application image, kiểm soát rollback, bảo vệ key và giữ chain of trust đủ chặt. Nếu chỉ dựa vào CRC, encryption hoặc một bước verify đơn lẻ thì vẫn chưa đủ để gọi là secure update.

Phản hồi về bài viết

Cùng thảo luận chút nhỉ!

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.