انتقل إلى المحتوى الرئيسي

STM32H743 - وحدة التحكم في الوصول الفعلي Ada/SPARK

يعمل STM32H743 بمثابة وحدة تحكم في الوصول الفعلي مع ضمانات التحقق الرسمية. تمت كتابته في Ada 2022 مع تعليقات SPARK التوضيحية وطبقة Aurora HAL المخصصة، وهو يوفر دليلًا رياضيًا على صحة العمليات الأمنية الحرجة (التحكم في الترحيل) أثناء الوصول إلى الأجهزة الطرفية الحقيقية STM32H7 (مسرع HASH، GPIO، ADC، RNG).

دور في الهندسة المعمارية

المواصفات الفنية

ميزةالتفاصيل
MCUSTM32H743 (ARM Cortex-M7، 480 ميجاهرتز، الإصدار المزدوج)
كبش512 كيلو بايت AXI-SRAM + 128 كيلو بايت DTCM + 128 كيلو بايت SRAM1–4
فلاش2 ميجا بايت (الذاكرة المعينة عند 0x0800_0000)
لغةAda 2022 مع التحقق الرسمي من SPARK 2014
** وقت التشغيل **light-tasking-stm32h7 (GNAT، يمكّن delay)
التشفيرمسرع التجزئة (جهاز SHA-256)، ECDSA P-256 (برنامج mbedTLS)
** الاتصال **إيثرنت (LWIP TCP + mbedTLS TLS + MQTT 3.1.1)
** تخزين المفاتيح **منطقة OTP (0x1FF0_F000، الكتابة مرة واحدة)
** هال **Aurora_HAL (SPARK_Mode Off) — GPIO، وADC، وHASH، وRNG، وTCP، وTLS
فاصل زمني للحلقة5 ثواني

لماذا آدا/سبارك؟

ميزةأدا/سباركجRust
التحقق الرسميGNATprove (الدليل الرياضي)فراما-سي (معقد)غير متوفر
** سلامة وقت التشغيل **لا يوجد تجاوزات في المخزن المؤقت (ثبت)يدويوقت الترجمة (Rust)
التصميم بموجب العقدأصلي (قبل/بعد/النوع_غير المتغير)القائمة على المكتبةليس مواطنا
في الوقت الحالىالملف الشخصي Ravenscar (حتمية)لا ضماناتلا ضمانات
DO-178C / IEC 61508معتمديمكن التصديق عليهاليس بعد
اعتماد الصناعةالسكك الحديدية والفضاء والدفاععالميتزايد

بالنسبة لوحدة التحكم التي تفتح/تغلق الأبواب المادية، فإن الدليل الرياضي على الصحة ليس رفاهية - بل هو أحد متطلبات السلامة. قد يؤدي وجود خلل في التحكم في التتابع إلى حبس الأشخاص داخل مبنى محترق.

التحكم في التتابع المعتمد من SPARK

تحتوي وحدة التحكم في الترحيل على عقود رسمية يتحقق منها GNAT رياضيًا:

-- relay_control.ads — SPARK-proven relay specification
package Relay_Control with SPARK_Mode is
type Relay_State is (Open, Closed);
type Attestation_Status is (Not_Verified, Verified, Revoked);

Current_State : Relay_State := Open;
Current_Attestation : Attestation_Status := Not_Verified;

procedure Set_Relay
(State : in Relay_State;
Status : in Attestation_Status)
with
Global => (Output => (Current_State, Current_Attestation)),
Pre => (if State = Closed then Status = Verified),
Post => (if Status = Revoked then Current_State = Open);

function Get_State return Relay_State
with Global => (Input => Current_State);

function Get_Attestation return Attestation_Status
with Global => (Input => Current_Attestation);
end Relay_Control;
-- relay_control.adb — SPARK body with non-SPARK GPIO wrapper
with Aurora_HAL;
package body Relay_Control with SPARK_Mode is
-- Local non-SPARK procedure writes hardware GPIO register
procedure Write_Relay_GPIO with SPARK_Mode => Off is
begin
case Current_State is
when Open => Aurora_HAL.GPIO_Write
(Aurora_HAL.Relay_Port, Aurora_HAL.Relay_Pin, Aurora_HAL.Low);
when Closed => Aurora_HAL.GPIO_Write
(Aurora_HAL.Relay_Port, Aurora_HAL.Relay_Pin, Aurora_HAL.High);
end case;
end Write_Relay_GPIO;

procedure Set_Relay
(State : in Relay_State; Status : in Attestation_Status)
is
begin
if Status = Revoked then
Current_State := Open;
else
Current_State := State;
end if;
Current_Attestation := Status;
Write_Relay_GPIO; -- non-SPARK GPIO register access
end Set_Relay;

function Get_State return Relay_State is (Current_State);
function Get_Attestation return Attestation_Status is (Current_Attestation);
end Relay_Control;

ما ضمانات GNATprove

تشغيل gnatprove على هذا الكود يثبت رياضيًا:

  1. من المستحيل إغلاق التتابع بدون شهادة صالحة — الشرط المسبق يمنع ذلك في وقت الترجمة
  2. تفتح الشهادة الملغاة دائمًا التتابع — الشرط اللاحق يضمن ذلك
  3. لا توجد استثناءات لوقت التشغيل — لا يوجد قسمة على صفر، ولا يوجد تجاوز، ولا توجد مصفوفة خارج الحدود
  4. لا توجد متغيرات غير مهيأة — تتم تهيئة كافة المسارات قبل الاستخدام

الحلقة الرئيسية

-- main.adb
with Aurora_HAL;
procedure Main with SPARK_Mode is
Attestation : Relay_Control.Attestation_Status;
Tamper : Tamper_Detection.Tamper_Event;
begin
-- Initialize hardware: RCC clocks, GPIO, ADC, HASH, RNG
Aurora_HAL.System_Init;
Aurora_HAL.ADC_Init;
Aurora_HAL.GPIO_Configure (Aurora_HAL.Relay_Port, Aurora_HAL.Relay_Pin,
Aurora_HAL.Output, Aurora_HAL.No_Pull);
Aurora_HAL.GPIO_Configure (Aurora_HAL.Case_Open_Port, Aurora_HAL.Case_Open_Pin,
Aurora_HAL.Input, Aurora_HAL.Pull_Up);
Aurora_HAL.GPIO_Configure (Aurora_HAL.Wire_Cut_Port, Aurora_HAL.Wire_Cut_Pin,
Aurora_HAL.Input, Aurora_HAL.Pull_Up);
MQTT_Publisher.Connect (Host => "mosquitto", Port => 8883);

loop
-- 1. Verify firmware attestation (every loop = every 5s)
Attest_Status := Vault_Attestation.Verify_Device_Certificate;

-- 2. Control relay based on attestation
if Attest_Status = Relay_Control.Verified then
Relay_Control.Set_Relay (Closed, Attest_Status);
else
Relay_Control.Set_Relay (Open, Attest_Status);
end if;

-- 3. Publish status
MQTT_Publisher.Publish (
Topic => "aurora/sensors/stm32_pac_01/status",
Payload => Build_Status_Payload (Attest_Status),
QoS => At_Least_Once
);

-- 4. Check tamper sensors
Tamper := Tamper_Detection.Check_Tamper;
if Tamper /= Tamper_Detection.None then
MQTT_Publisher.Publish (
Topic => "aurora/sensors/stm32_pac_01/alerts",
Payload => Build_Tamper_Alert (Tamper),
QoS => Exactly_Once
);
end if;

-- 5. Publish telemetry
MQTT_Publisher.Publish (
Topic => "aurora/sensors/stm32_pac_01/telemetry",
Payload => Build_Telemetry_Payload,
QoS => At_Least_Once
);

-- Wait 5 seconds
delay 5.0;
end loop;
end Main;

شهادة Vault

package Vault_Attestation
with SPARK_Mode,
Abstract_State => Attestation_State
is
subtype Hash_String is String (1 .. 64); -- SHA-256 hex (64 chars)

procedure Verify_Device_Certificate
(Result : out Relay_Control.Attestation_Status)
with Global => (In_Out => Attestation_State);

function Get_Firmware_Hash return Hash_String
with Global => null; -- pure flash read via non-SPARK HAL

function Get_Boot_Count return Natural
with Global => (Input => Attestation_State);
end Vault_Attestation;

يستخدم STM32 الأجهزة الطرفية لعمليات التشفير:

عمليةالأجهزةغاية
علامة ECDSA P-256برنامج mbedTLS (STM32H7 يفتقر إلى PKA)توقيعات الشهادة
شا-256مسرع التجزئةتجزئة البرامج الثابتة
تخزين المفاتيحمنطقة مكتب المدعي العامالمفتاح الخاص (الكتابة مرة واحدة)
شهادةقسم الفلاشVault-إصدار x.509

كشف العبث

package Tamper_Detection is

type Tamper_Event is (None, Case_Open, Wire_Cut, Voltage_Anomaly, Temperature_Anomaly);
type Tamper_Severity is (Normal, Warning, Critical);

function Check_Tamper return Tamper_Event;
function Get_Severity (Event : Tamper_Event) return Tamper_Severity;

end Tamper_Detection;
حدثطريقة الكشفخطورة
Case_Openمفتاح ميكانيكي على PA0 (سحب لأعلى، منخفض نشط)تحذير
Wire_Cutحلقة الاستمرارية على PA1 (سحب لأعلى، انخفاض نشط)شديد الأهمية
Voltage_AnomalyADC1 ch4 على PA4 (نافذة 2.8–3.3 فولت، 12 بت)تحذير
Temperature_Anomalyمستشعر درجة الحرارة الداخلي عبر ADC3 ch18 (-20 إلى +70 درجة مئوية)شديد الأهمية

الناشر MQTT

package MQTT_Publisher
with SPARK_Mode,
Abstract_State => Connection_State
is
type QoS_Level is (At_Most_Once, At_Least_Once, Exactly_Once);

procedure Connect (Host : in String; Port : in Natural)
with Global => (Output => Connection_State);

procedure Publish
(Topic : in String;
Payload : in String;
QoS : in QoS_Level := At_Least_Once)
with Global => (In_Out => Connection_State);

procedure Disconnect
with Global => (In_Out => Connection_State);

function Is_Connected return Boolean
with Global => (Input => Connection_State);
end MQTT_Publisher;

يتصل STM32 بـ mTLS باستخدام شهادات x.509 الصادرة عن Vault:

  • شهادة العميل: ECDSA P-256، الصادرة عن Vault PKI
  • شهادة CA: Vault root CA
  • إصدار TLS: 1.3

بناء النظام

# Build with GNAT (Ada compiler)
gprbuild -P firmware/stm32/aurora_stm32.gpr -XBUILD=release

# Run SPARK formal verification
gnatprove -P firmware/stm32/aurora_stm32.gpr --level=2 --prover=z3

# Flash via ST-Link
st-flash write firmware/stm32/bin/main.bin 0x08000000

مستويات مقاومة الشرارة

مستوىما يثبتوقت
0تحليل التدفق (لا توجد قراءات غير مهيأة)ثواني
1+ لا توجد استثناءات في وقت التشغيل (التجاوز، النطاق)دقائق
2*** استيفاء العقود (الشروط المسبقة/اللاحقة)**دقائق
3+ ثبت جميع التأكيداتساعات
4+ صحة وظيفية كاملةساعات+

يستخدم AuroraSOC المستوى 2 - وهو ما يكفي لإثبات ثبات سلامة التتابع.