Condividi tramite


Guida allo sviluppo per enclave di sicurezza basata su virtualizzazione

Si applica a:✅ Windows 11 Build 26100.2314 o versione successiva di Windows Server 2025 o versione ✅ successiva

Questa guida di sviluppo descrive come compilare, firmare ed eseguire il debug di un enclave VBS di base.

Prerequisiti

Per iniziare a usare le enclave VBS, è necessario soddisfare i requisiti seguenti:

  • Visualizzare e soddisfare i requisiti dei dispositivi nella panoramica delle enclave VBS.
  • Visualizzare e soddisfare i prerequisiti di sviluppo nella panoramica delle enclave VBS.
    • È consigliabile installare il carico di lavoro Sviluppo di applicazioni desktop con C++ tramite il programma di installazione di Visual Studio. Installerà tutti gli strumenti necessari, incluso Windows Software Development Kit (SDK).
  • Scaricare il codice di esempio da GitHub. Illustra il ciclo di vita di un enclave VBS, incluso come effettuare chiamate di funzione nell'enclave.
    • Ogni enclave deve avere un'app host. Il codice di esempio contiene una soluzione di Visual Studio con due progetti, ovvero l'host dell'enclave e l'enclave di test.

Introduzione

Dopo aver soddisfatto i prerequisiti precedenti, dovrebbe essere possibile aprire il file della soluzione dall'esempio VbsEnclave in Visual Studio e compilarlo. Crea un'applicazione di test insieme all'enclave corrispondente. Tuttavia, non è possibile eseguire correttamente l'applicazione fino a quando l'enclave non è firmato con un certificato valido.

Questa guida illustra in dettaglio come creare un enclave VBS di base nel computer di sviluppo. I passaggi per la creazione di un enclave VBS sono i seguenti:

  1. Scrivere una DLL dell'enclave VBS e un'applicazione host corrispondente
  2. Compilare la DLL e l'host
  3. Firmare la DLL dell'enclave VBS
  4. Eseguire il debug dell'enclave VBS

Per iniziare, è possibile comprendere il ciclo di vita di un enclave. Le API enclave vengono chiamate nell'ordine seguente:

Diagramma che illustra l'ordine in cui vengono chiamate le API enclave VBS

Passaggio 1: Scrittura di enclave VBS

Si esaminerà il codice di esempio e si apprenderà come scrivere un'applicazione che usa un enclave VBS.

Scrittura dell'host dell'enclave

Tenere presente che una DLL dell'enclave VBS è semplicemente una DLL e quindi richiede un'applicazione host. L'applicazione host non è altro che un'applicazione Windows standard. Per usare enclave VBS, l'host deve usare le API dell'enclave di Windows dall'intestazione enclaveapi.h. L'inclusione windows.h nell'applicazione host fornirà l'accesso a queste API.

Scrittura della DLL da caricare in un enclave di test

Fare riferimento al codice di esempio nel progetto enclave di test per seguire la procedura seguente.

Nell'esempio di enclave viene creata una semplice enclave che esegue L'XOR dell'input con 0xDADAF00D e restituisce il risultato. Di seguito viene descritto come eseguire questa operazione:

  1. Iniziare includendo winenclave.h. Nel codice di esempio fare riferimento a Samples/VbsEnclave/Test enclave/precomp.h:

    #include <winenclave.h>
    

    winenclave.hè il file di inclusione centrale per le enclave VBS e include windows.h, , ntenclv.hwinenclaveapi.h.

  2. Ogni DLL caricata in un enclave richiede una configurazione. Questa configurazione viene definita usando una variabile globale const denominata __enclave_config di tipo IMAGE_ENCLAVE_CONFIG. Nel codice di esempio fare riferimento a Samples/VbsEnclave/Test enclave/enclave.c:

    const IMAGE_ENCLAVE_CONFIG __enclave_config = {
        sizeof(IMAGE_ENCLAVE_CONFIG),
        IMAGE_ENCLAVE_MINIMUM_CONFIG_SIZE,
        IMAGE_ENCLAVE_POLICY_DEBUGGABLE,    // DO NOT SHIP DEBUGGABLE ENCLAVES TO PRODUCTION
        0,
        0,
        0,
        { 0xFE, 0xFE },    // family id
        { 0x01, 0x01 },    // image id
        0,                 // version
        0,                 // SVN
        0x10000000,        // size
        16,                // number of threads
        IMAGE_ENCLAVE_FLAG_PRIMARY_IMAGE
    };
    

    Nota

    Può essere presente una sola immagine primaria per enclave. Se si caricano più immagini primarie, quella caricata per prima viene considerata primaria e il resto viene considerato come dipendenze. In questo esempio non esistono dipendenze diverse dalle DLL della piattaforma enclave.

  3. La DllMain() funzione è obbligatoria e definisce il punto di ingresso nell'enclave. Viene chiamato durante InitializeEnclave(). Nel codice di esempio fare riferimento a Samples/VbsEnclave/Test enclave/enclave.c.

    BOOL
    DllMain(
        _In_ HINSTANCE hinstDLL,
        _In_ DWORD dwReason,
        _In_ LPVOID lpvReserved
    )
    {
        UNREFERENCED_PARAMETER(hinstDLL);
        UNREFERENCED_PARAMETER(lpvReserved);
    
        if (dwReason == DLL_PROCESS_ATTACH) {
            InitialCookie = 0xDADAF00D;
        }
    
        return TRUE;
    }
    
  4. Tutte le funzioni all'interno dell'enclave chiamate dall'applicazione host devono essere esportate e di tipo LPENCLAVE_ROUTINE. La firma della funzione è simile alla seguente:

    void* CALLBACK enclaveFunctionName(_In_ void* Context)
    

    Nel codice di esempio fare riferimento a Samples/VbsEnclave/Test enclave/enclave.c.

    void*
    CALLBACK
    CallEnclaveTest(
        _In_ void* Context
    )
    {
        WCHAR String[32];
        swprintf_s(String, ARRAYSIZE(String), L"%s\n", L"CallEnclaveTest started");
        OutputDebugStringW(String);
    
        return (void*)((ULONG_PTR)(Context) ^ InitialCookie);
    }
    

    Nota

    È possibile accedere solo alle funzioni esportate dall'immagine dell'enclave primaria dall'applicazione host.

    È quindi possibile esportare la funzione usando un .DEF file. Nel codice di esempio fare riferimento a Samples/VbsEnclave/Test enclave/vbsenclave.def. Per altre informazioni, vedere Esportazione da una DLL tramite file DEF.

Ed è così che si scrive una DLL di enclave VBS di base.

Passaggio 2: Compilazione di enclave VBS

Dopo aver scritto la DLL dell'enclave VBS, è possibile compilarla.

Compilazione dell'host dell'enclave

La compilazione dell'app host equivale alla compilazione di qualsiasi applicazione Windows, ma con l'aggiunta all'elenco onecore.lib delle dipendenze durante il collegamento.

Compilazione della DLL dell'enclave di test

Prima di poter compilare la DLL dell'enclave di test, sono necessarie alcune modifiche alle configurazioni del compilatore e del linker:

  1. Il linker MSVC fornisce un /ENCLAVE flag che seleziona i dettagli di configurazione dell'enclave. Il /ENCLAVE flag non è compatibile con il collegamento incrementale, quindi è necessario impostare /INCREMENTAL:NO.

  2. [Solo configurazione di debug] /EDITANDCONTINUE non è compatibile con /INCREMENTAL:NO, quindi viene usato /Zi invece di per il formato delle informazioni di /ZI debug nel compilatore.

  3. [Solo configurazione di debug] La configurazione Dei controlli di base del runtime deve essere impostata su Predefinito. I controlli degli errori di runtime non sono supportati nelle enclave VBS.

  4. La firma digitale di una DLL dell'enclave deve essere controllata in fase di caricamento e richiede l'impostazione del /INTEGRITYCHECK flag nel linker.

  5. Le DLL enclave devono essere instrumentate per Control Flow Guard (CFG) per cui viene usato il /GUARD:MIXED flag nel linker.

  6. Le enclave hanno versioni personalizzate di librerie platform, startup, runtime e UCRT. Per assicurarsi di non collegare le versioni non enclave, usare il /NODEFAULTLIB flag . Successivamente, aggiungere le librerie corrette in AdditionalDependencies. Nel codice di esempio queste librerie vengono incapsulate nella macro VBS_Enclave_Dependencies . Di seguito sono riportate le librerie di enclave VBS:

    1. libcmt.lib e libvcruntime.lib : disponibile nella enclave cartella con gli strumenti di compilazione di Visual C++, vedere I file lib (CRT) e C++ Standard Library (STL).
    2. vertdll.lib e bcrypt.lib : disponibile nella um cartella con le librerie di Windows SDK.
    3. ucrt.lib - Trovato nella ucrt_enclave cartella con le librerie di Windows SDK.

Nota

Non sono supportate altre librerie di piattaforma all'interno di enclave VBS.

In sintesi, sono necessarie le modifiche seguenti:

Compilatore (solo configurazione di debug):

  • Formato informazioni di debug: /Zi
  • Controlli di runtime di base: Default

Linker:

  • /ENCLAVE
  • /NODEFAULTLIBS + AdditionalDependencies
  • /INCREMENTAL:NO
  • /INTEGRITYCHECK
  • /GUARD:MIXED

È ora possibile compilare la DLL dell'enclave.

Protezione con VEIID

VEIID (l'utilità di associazione DELL'ID importazione enclave VBS) è uno strumento di Windows SDK che aggiorna le tabelle di importazione all'interno di un enclave VBS con ID noti per le DLL della piattaforma. Ciò migliora la sicurezza delle enclave VBS impedendo il caricamento di una DLL dannosa (firmata) con lo stesso nome di una delle DLL della piattaforma.

Nel codice di esempio questa operazione viene eseguita automaticamente come evento di post-compilazione.

Nota

È consigliabile evitare di usare DLL non primarie diverse dalle DLL della piattaforma. Mantenere invece tutto il codice all'interno della DLL dell'enclave stessa.

Passaggio 3: Firma di DLL enclave VBS

Le enclave VBS devono essere firmate per essere caricate correttamente. La firma in un enclave contiene informazioni sull'autore dell'enclave. Viene usato per derivare l'ID autore per un enclave. È possibile firmare l'enclave prima di firmarla per la produzione.

Firma di test - Locale

Ogni certificato di firma dell'enclave richiede almeno 3 EKU:

  1. EKU per la firma del codice - 1.3.6.1.5.5.7.3.3

  2. Enclave EKU - 1.3.6.1.4.1.311.76.57.1.15

  3. Autore EKU: L'EKU è nel formato 1.3.6.1.4.1.311.97.X.Y.Z, dove X è maggiore di 999.

    Per i test, è possibile scegliere di usare qualsiasi EKU autore che corrisponda a questo modello. Per la produzione, verrà fornito un EKU autore come parte del certificato di produzione (di seguito sono riportati altri dettagli sulla firma di produzione).

    Esempio: 1.3.6.1.4.1.311.97.814040577.346743379.4783502.105532346

Se si vuole firmare la DLL dell'enclave durante lo sviluppo, abilitare la firma di test. Con la firma di test abilitata, è possibile creare un certificato contenente questi tre EKU e firmare l'enclave con esso. È possibile usare il cmdlet New-SelfSignedCertificate per creare un certificato. Si noti che le DLL dell'enclave devono essere con segno hash di pagina.

Nota

Dopo aver ottenuto un certificato, è possibile automatizzare il processo di firma nell'evento di post-compilazione.

New-SelfSignedCertificate -CertStoreLocation Cert:\\CurrentUser\\My -DnsName "MyTestEnclaveCert" -KeyUsage DigitalSignature -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256 -TextExtension "2.5.29.37={text}1.3.6.1.5.5.7.3.3,1.3.6.1.4.1.311.76.57.1.15,1.3.6.1.4.1.311.97.814040577.346743379.4783502.105532346"
signtool sign /ph /fd SHA256 /n "MyTestEnclaveCert" vbsenclave.dll

Dopo aver firmato la DLL dell'enclave, è ora possibile caricarla in un ambiente con firma di test abilitata.

Firma di produzione: firma attendibile (in precedenza firma del codice di Azure)

La firma di produzione per le enclave viene fornita tramite il profilo certificato dell'enclave VBS in Firma attendibile. Per informazioni dettagliate su come usare la firma attendibile, vedere la documentazione.

La firma attendibile consente anche di firmare l'enclave dalla riga di comando. In questo modo viene restituito un enclave firmato pronto per l'esecuzione quando si compila l'enclave in Visual Studio.

Passaggio 4: Debug di enclave VBS

In genere, la memoria di un enclave è nascosta dai debugger ed è protetta da VTL0. Tuttavia, se si vuole eseguire il debug della DLL dell'enclave VBS, è possibile compilarli per il debug durante lo sviluppo. Le enclave sono un processo in modalità utente VTL1 e pertanto possono essere sottoposto a debug con un debugger in modalità utente.

Per rendere il debug dell'enclave:

  1. La configurazione dell'immagine DLL dell'enclave deve consentire il debug : questa operazione viene eseguita impostando il flag IMAGE_ENCLAVE_POLICY_DEBUGGABLE in IMAGE_ENCLAVE_CONFIG.
  2. Il debug deve essere consentito durante la creazione dell'enclave: questa operazione viene eseguita impostando il flag ENCLAVE_VBS_FLAG_DEBUG nella struttura ENCLAVE_CREATE_VBS_INFO passata alla chiamata CreateEnclave .

Per eseguire il debug dell'enclave:

  1. Collegare il debugger in modalità utente al processo host dell'enclave.
  2. Ricaricare i simboli dell'enclave dopo che il processo host ha caricato l'immagine dell'enclave in memoria.
  3. Impostare punti di interruzione nelle funzioni all'interno dell'enclave. Il debugger si interrompe in una chiamata di enclave.

È anche possibile interrompere i punti di interruzione in modalità utente per CreateEnclave, InitializeEnclave e così via, oltre a eseguire ulteriori passaggi nel codice corrispondente in ntdll.dll.

Nota

Non usare mai enclave di cui è possibile eseguire il debug negli ambienti di produzione.

A questo scopo, è ora possibile compilare e distribuire la prima enclave VBS. In caso di domande, contattare il supporto per sviluppatori Windows.

Panoramica degli enclave VBS

Firma attendibile di Azure

Intestazione enclaveapi.h

API disponibili negli enclave VBS