Cette rubrique explique comment créer une application Intel Software Guard Extensions (SGX) 2.0 à l'aide du SDK d'environnement d'exécution de confiance (TEE), puis l'empaqueter et la déployer sur un cluster de calcul confidentiel ACK. L'application d'exemple, helloworld, s'exécute dans une enclave, génère périodiquement des messages et les affiche dans le terminal.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Un cluster géré ACK pour le calcul confidentiel. Consultez Créer un cluster de calcul chiffré et un pool de nœuds.
Un accès SSH ou Cloud Assistant à une instance prenant en charge le calcul confidentiel.
Git installé, ou la possibilité de l'installer avec
sudo yum install git.Docker installé. Consultez Installer et utiliser Docker sur une instance Linux.
kubectlconfiguré pour se connecter à votre cluster ACK.
Fonctionnement
Une application Intel SGX 2.0 comprend deux composants :
Composant non approuvé : mémoire non chiffrée contenant la fonction d'entrée
main()et les implémentations OCALL (outside call). Dans le diagramme,main()etbar()s'exécutent dans le composant non approuvé.Composant approuvé (enclave) : mémoire chiffrée créée et protégée par le CPU. Seul le CPU peut accéder au code et aux données qu'elle contient. Dans le diagramme,
helloworld()etfoo()s'exécutent dans l'enclave.
L'application utilise ECALL (enclave call) pour appeler des fonctions de l'enclave depuis du code non approuvé. Inversement, elle recourt à OCALL pour invoquer des fonctions non approuvées depuis l'intérieur de l'enclave. Ces deux mécanismes sont déclarés dans des fichiers EDL (Enclave Definition Language).
Exemple de code et structure de répertoire
Le code source de helloworld est disponible sur GitHub. Il comprend le code source de l'application, le Makefile et le Dockerfile.
Structure de premier niveau :
sgx-device-plugin/samples/hello_world/
├── Dockerfile
├── Makefile
├── README.md
└── src
├── App
│ ├── App.cpp
│ └── App.h
├── Enclave
│ ├── Enclave.config.xml
│ ├── Enclave.cpp
│ ├── Enclave.edl
│ ├── Enclave.h
│ ├── Enclave.lds
│ └── Enclave_private.pem
└── Makefile
Le répertoire src contient deux sous-répertoires :
|
Répertoire |
Description |
Fichiers clés |
|
|
Code non approuvé : fonction d'entrée |
|
|
|
Code approuvé exécuté dans l'enclave |
|
Fichiers sources principaux
Enclave/Enclave.edl — déclare l'interface ECALL et OCALL. Toute application SGX doit comporter au moins un bloc trusted {} (ECALL) ou un bloc untrusted {} (OCALL) dans le fichier EDL.
Dans cet exemple, l'application ne nécessite qu'un seul ECALL : ecall_hello_from_enclave. Celui-ci alloue un tampon dans l'enclave, y inscrit « Hello world », puis copie ce contenu vers un tampon non approuvé afin que le composant non approuvé puisse appeler printf.
enclave {
trusted {
public void ecall_hello_from_enclave([out, size=len] char* buf, size_t len);
};
};
Enclave/Enclave.config.xml — définit les limites de ressources d'exécution de l'enclave. Trois groupes de paramètres régissent le comportement de la mémoire et des threads :
Paramètres TCS (
TCSNum,TCSPolicy) :TCSNumfixe le nombre de Thread Control Structures, déterminant ainsi le nombre de threads exécutables simultanément dans l'enclave.TCSPolicyindique si les emplacements TCS sont liés aux threads du système d'exploitation ou s'ils peuvent être réutilisés.Paramètres de pile (
StackMaxSize) : taille maximale de pile allouée à chaque thread de l'enclave. Augmentez cette valeur si votre enclave utilise des piles d'appels profondes ou de grandes variables locales.Paramètres de tas (
HeapMaxSize) : taille maximale du tas disponible pour l'enclave. Ajustez ce paramètre en fonction de la mémoire dynamique allouée par le code de votre enclave.
Pour les versions de production, passez la valeur de DisableDebug de 0 à 1 afin d'empêcher tout débogueur de s'attacher à l'enclave.
<EnclaveConfiguration>
<ProdID>0</ProdID>
<ISVSVN>0</ISVSVN>
<StackMaxSize>0x40000</StackMaxSize>
<HeapMaxSize>0x100000</HeapMaxSize>
<TCSNum>10</TCSNum>
<TCSPolicy>1</TCSPolicy>
<!-- Change 'DisableDebug' to 1 before release to prevent debugger access -->
<DisableDebug>0</DisableDebug>
<MiscSelect>0</MiscSelect>
<MiscMask>0xFFFFFFFF</MiscMask>
</EnclaveConfiguration>
Enclave/Enclave_private.pem — clé privée RSA servant à signer enclave.so. Générez-la avec la commande suivante :
openssl genrsa -out Enclave/Enclave_private.pem -3 3072
Étape 1 : Compiler l'application hello_world
-
Installez Git :
sudo yum install git -
Clonez le dépôt et lancez la compilation :
git clone https://github.com/AliyunContainerService/sgx-device-plugin cd sgx-device-plugin/samples/hello_world SGX_SDK=/opt/alibaba/teesdk/intel/sgxsdk make buildLa compilation exécute six étapes :
sgx_edger8ret la fonction ECALLsgx_ecallproduisent le code stub non approuvé (Enclave_u.c,Enclave_u.h) dans le répertoireApp.Compilation des fichiers binaires non approuvés situés dans
App.sgx_edger8rgénère le code approuvé (Enclave_t.c,Enclave_t.h) dans le répertoireEnclave.Compilation d'
enclave.soen tant que bibliothèque dynamique liée approuvée.sgx_signsigneenclave.so, ce qui produitenclave.signed.so.Édition des liens du binaire final
hello_world.
Une compilation réussie se termine par une sortie similaire à :
GEN => App/Enclave_u.h CC <= App/Enclave_u.c CXX <= App/App.cpp LINK => app GEN => Enclave/Enclave_t.h CC <= Enclave/Enclave_t.c CXX <= Enclave/Enclave.cpp LINK => enclave.so ... tcs_num 10, tcs_max_num 10, tcs_min_pool 1 The required memory is 3960832B. The required memory is 0x3c7000, 3868 KB. Succeed. SIGN => enclave.signed.so The project has been built in debug hardware modeVérifiez que la dernière ligne affiche bien
The project has been built in debug hardware mode. Cela confirme que la compilation a utilisé le matériel SGX réel (et non le mode simulation) et que la signature s'est terminée avec succès. Arborescence des fichiers compilés :sgx-device-plugin/samples/hello_world/src/ ├── hello_world #[generated] ├── App │ ├── App.cpp │ ├── App.h │ ├── App.o #[generated] │ ├── Enclave_u.c #[generated] │ ├── Enclave_u.h #[generated] │ └── Enclave_u.o #[generated] ├── Enclave │ ├── Enclave.config.xml │ ├── Enclave.cpp │ ├── Enclave.edl │ ├── Enclave.h │ ├── Enclave.lds │ ├── Enclave.o #[generated] │ ├── Enclave_private.pem │ ├── Enclave_t.c #[generated] │ ├── Enclave_t.h #[generated] │ └── Enclave_t.o #[generated] ├── enclave.signed.so #[generated] ├── enclave.so #[generated] └── Makefile -
Exécutez l'application sur une instance compatible SGX pour vérifier son bon fonctionnement :
cd src/ ./hello_worldSortie attendue :
Wed May 6 06:53:33 2020 Hello world From SGX Enclave! Wed May 6 06:53:34 2020 Hello world From SGX Enclave! ...
Étape 2 : Créer et déployer l'application helloworld
Utilisez une image de base Alibaba Cloud Linux et installez la dernière version du SDK SGX. Mettez régulièrement à jour le SDK pour bénéficier des correctifs de sécurité.
Exemple de Dockerfile
FROM registry.cn-hangzhou.aliyuncs.com/alinux/alinux3
ARG REGION_ID=cn-hangzhou
RUN yum install -y curl && \
repo_url=https://enclave-${REGION_ID}.oss-${REGION_ID}.aliyuncs.com/repo/alinux/enclave-expr.repo && \
yum install -y yum-utils && \
yum-config-manager --add-repo ${repo_url} && \
yum install -y libsgx-urts libsgx-uae-service # Add more SGX runtime dependencies on demand.
WORKDIR /src
COPY src/hello_world src/enclave.signed.so /src
ENTRYPOINT ["/src/hello_world"]
Le Dockerfile installe deux packages d'exécution SGX obligatoires :
libsgx-urts: système d'exécution non approuvé SGX, indispensable pour charger et exécuter les enclaves.libsgx-uae-service: bibliothèque de services de plateforme dédiée à l'attestation distante et aux opérations associées.
Créer et pousser l'image conteneur
-
Créez et poussez l'image conteneur. Remplacez
${IMAGE_URL}par l'adresse de votre registre d'images :cd sgx-device-plugin/samples/hello_world TARGET_IMAGE=${IMAGE_URL} SGX_SDK=/opt/alibaba/teesdk/intel/sgxsdk make image docker push ${IMAGE_URL} -
Déployez l'application
helloworldsur votre cluster ACK. Remplacez${IMAGE_URL}par l'adresse d'image obtenue à l'étape précédente :cat <<EOF | kubectl create -f - apiVersion: apps/v1 kind: Deployment metadata: name: helloworld namespace: default spec: replicas: 2 selector: matchLabels: app: helloworld template: metadata: labels: app: helloworld spec: containers: - image: ${IMAGE_URL} imagePullPolicy: Always name: helloworld resources: limits: cpu: 250m memory: 512Mi alibabacloud.com/sgx_epc_MiB: 2 EOF