Démarrage sécurisé dans i.MX6

Démarrage sécurisé dans i.MX6


Lors du développement de tout projet de systÚmes embarqués, le développeur doit résoudre deux problÚmes supplémentaires:

  • Comment protĂ©ger le firmware de l'usurpation d'identitĂ© dans le produit;
  • Comment protĂ©ger les logiciels contre la copie.

Cet article explique comment protéger le processeur i.MX6 contre la modification du chargeur de démarrage dans le produit et compliquer le processus de copie du micrologiciel.



introduction


Pour protĂ©ger la propriĂ©tĂ© intellectuelle dans le cas oĂč le projet de mĂ©tal nu [1] aide principalement le complexe matĂ©riel, Ă  la fois prĂ©sent dans le microcontrĂŽleur et externe. Des exemples sont donnĂ©s sur un site rĂ©putĂ© [2] . Des mĂ©thodes logicielles supplĂ©mentaires, telles que [3] sont utilisĂ©es, cependant, elles sont basĂ©es sur le mĂ©canisme de protection inconnu. Cela est dĂ» Ă  la faible puissance de calcul des appareils et Ă  l'inconvĂ©nient de mettre en Ɠuvre la gĂ©nĂ©ration dynamique de micrologiciels.

Lorsque SoC entre en jeu avec des systĂšmes d'exploitation comme Linux, la protection doit ĂȘtre organisĂ©e simultanĂ©ment Ă  plusieurs niveaux:

  • Fin du niveau d'application
  • Niveau du systĂšme d'exploitation
  • Niveau du chargeur de dĂ©marrage

En cas d'accĂšs Ă  l'un des niveaux, il est assez facile d'influencer le logiciel Ă  d'autres niveaux et de modifier les interactions entre les niveaux.
Les exemples les plus simples: votre logiciel installĂ© sur Linux communique via le protocole UART (par exemple, via / dev / ttyACM0) avec un microcontrĂŽleur. Un attaquant accĂ©dant au systĂšme utilise la mĂȘme ressource UART et rĂ©pĂšte des packages envoyĂ©s au hasard. Ou, par exemple, si un pilote est intĂ©grĂ© au noyau, un attaquant recompile le noyau en rĂ©Ă©crivant le code du pilote UART d'une autre maniĂšre. L'application finale ne sait pas ce qui se passe.

Qu'est-ce qu'un démarrage sécurisé et pourquoi est-il nécessaire?


Le premier niveau de protection de votre logiciel sur le systÚme cible est le démarrage sécurisé. Ci-aprÚs, le démarrage sécurisé est expliqué pour les processeurs de la famille i.MX6.

Le démarrage sécurisé dans i.MX6 est implémenté via un démarrage à haute assurance (HAB) et peut remplir deux fonctions:

  • dĂ©marrage sĂ©curisĂ©
  • tĂ©lĂ©chargement cryptĂ©.

Dans cet article, je vais dĂ©crire le processus permettant de garantir un chargement sĂ»r du processeur. I.MX6 implĂ©mente Ă©galement un algorithme qui fournit le chiffrement du chargeur de dĂ©marrage. Cependant, son utilisation nĂ©cessite la gĂ©nĂ©ration d'un chargeur de dĂ©marrage unique pour chaque produit, car il utilise une fonction de chiffrement unique pour chaque processeur. Il s'agit d'une procĂ©dure peu pratique dans la sĂ©rie, donc je ne l'ai pas dĂ©crite. Si vous avez quelque chose Ă  dire Ă  ce sujet, je serai heureux de l’entendre.
Le démarrage sécurisé tente de garantir que le chargeur de démarrage démarre sur votre produit, avec le noyau que vous y avez chargé.

À propos de la dĂ©finition que j'ai donnĂ©e au dĂ©marrage sĂ©curisĂ©. Le dĂ©marrage sĂ©curisĂ© ne vous empĂȘche pas de copier le produit. Oui, cela rend la procĂ©dure plus difficile, mais pas beaucoup. Le chargeur de dĂ©marrage ne peut pas signer l'intĂ©gralitĂ© du FS, il ne fournit donc pas de protection au niveau du systĂšme d'exploitation et au niveau de l'application finale. Tout fonctionne de maniĂšre classique: grĂące au chiffrement asymĂ©trique. Je dĂ©crirai le processus sur les doigts, il peut ĂȘtre lu plus profondĂ©ment dans [4]. Le chargeur de dĂ©marrage indique le script du HAB, oĂč les zones de mĂ©moire signĂ©es sont indiquĂ©es et oĂč se trouve la signature numĂ©rique. La clĂ© publique est situĂ©e dans la mĂ©moire du processeur OTP (One time programmable). Lors du chargement, le script vĂ©rifie la zone de mĂ©moire spĂ©cifiĂ©e Ă  l'aide de la signature numĂ©rique jointe et d'une clĂ© cĂąblĂ©e. Si le test Ă©choue, le processeur ne dĂ©marre pas le tĂ©lĂ©chargement. Le fonctionnement HAB doit Ă©galement ĂȘtre activĂ© en dĂ©finissant un bit dans la rĂ©gion de mĂ©moire OTP.

Inconvénients du démarrage sécurisé:

  • Si le HAB n'est pas activĂ©, le micrologiciel dĂ©marre toujours. Cela signifie que sans ajouter. mĂ©thodes de protection votre micrologiciel s'exĂ©cutera sur une copie du produit. Afin d'Ă©viter que cela ne se produise, le chargeur de dĂ©marrage doit activer indĂ©pendamment le HAB au dĂ©marrage. Mais ensuite, en insĂ©rant une clĂ© USB dans un autre produit et en oubliant de flasher la clĂ© publique, vous pouvez jeter le processeur.
  • Lorsque vous accĂ©dez Ă  la mĂ©moire du processeur, vous pouvez copier la clĂ© publique, cela suffit pour copier le produit.

la mise en oeuvre


En gĂ©nĂ©ral, il y a beaucoup d'articles en anglais [5] [6] sur Internet sur le sujet de la mise en Ɠuvre, mais pas une seule mĂ©thode proposĂ©e n'a dĂ©collĂ© Ă  la fois, et les liens vers le logiciel ont commencĂ© Ă  disparaĂźtre, j'ai donc dĂ©cidĂ© de l'enregistrer comme un article principalement pour moi, lorsque Je reviendrai sur cette question Ă  l'avenir.

Vous devez d'abord télécharger le logiciel suivant: outil de signature de code [7] et les scripts nécessaires pour générer des clés et signer. Dans l'archive spécifiée, j'ai supprimé tous les utilitaires et bibliothÚques inutiles, car il y en a beaucoup inutilisés pour notre tùche.

Ensuite, vous devez générer les clés:

cd ${CST_PATH}/release/keys
echo ${serial} > serial //8 ,     
echo ${password} >  key_pass.txt //   ,     
echo ${password} >>  key_pass.txt //
./hab4_pki_tree.sh //     
Do you want to use an existing CA key (y/n)?: n 
Do you want to use Elliptic Curve Cryptography (y/n)?: n
Enter key length in bits for PKI tree: 4096
Enter PKI tree duration (years): 10
How many Super Root Keys should be generated? 4
Do you want the SRK certificates to have the CA flag set? (y/n)?: y
 ../linux64/bin/srktool -h 4 -t SRK_1_2_3_4_table.bin -e SRK_1_2_3_4_fuse.bin \
 -d sha256 -c ./SRK1_sha256_4096_65537_v3_ca_crt.pem,\
./SRK2_sha256_4096_65537_v3_ca_crt.pem,./SRK3_sha256_4096_65537_v3_ca_crt.pem,\
./SRK4_sha256_4096_65537_v3_ca_crt.pem -f 1

Le script de génération de clés soulÚve les questions ci-dessus. J'ai donné un exemple d'options standard. La réponse à ces questions détermine comment les clés générées et les paramÚtres des clés générées seront appelés. Pensez à d'autres commandes. Ensuite, nous lisons la clé publique nécessaire pour écrire dans le processeur. Nous utiliserons pour cela un script pratique de [5] .

cd ${CST_PATH}/release/linux64/bin
./var-u-boot_fuse_commands.sh 
fuse prog 3 0 0xFFFFFFFF //   uboot.
fuse prog 3 1 0xFFFFFFFF //     
fuse prog 3 2 0xFFFFFFFF //       .
fuse prog 3 3 0xFFFFFFFF //  -   .
fuse prog 3 4 0xFFFFFFFF //      .
fuse prog 3 5 0xFFFFFFFF //
fuse prog 3 6 0xFFFFFFFF  //
fuse prog 3 7 0xFFFFFFFF //

Cette tĂąche peut ĂȘtre appliquĂ©e Ă  uboot avec SPL intĂ©grĂ© ou avec SPL et uboot sĂ©parĂ©s (version rocko par exemple). J'Ă©cris une version pour que vous sachiez oĂč ils sont utilisĂ©s en standard. Si vous compilez uboot vous-mĂȘme, votre SPL sera trĂšs probablement intĂ©grĂ© Ă  uboot. Un point important dans le chargeur de dĂ©marrage defconfig est d'ajouter les options suivantes:

CONFIG_SECURE_BOOT=y
CONFIG_SYS_FSL_HAS_SEC=y 
#define CONFIG_SYS_FSL_SEC_COMPAT    4 /* HAB version */
#define CONFIG_FSL_CAAM
#define CONFIG_CMD_DEKBLOB
#define CONFIG_SYS_FSL_SEC_LE
#define CONFIG_FAT_WRITE

Ces options activent les pilotes pour travailler avec les modules matĂ©riels. Tout est comme dans menuconfig pour Linux. Lors de la compilation du chargeur de dĂ©marrage, utilisez le mode verbeux (supprimez V = 1. L'assembly avec ce paramĂštre est Ă©crit dans le guide. Cependant, je l'ai nettoyĂ© moi-mĂȘme). Dans ce cas, des informations sur l'adresse du point d'entrĂ©e et d'autres Ă©lĂ©ments nĂ©cessaires Ă  l'enregistrement d'une signature numĂ©rique sont ajoutĂ©es aux journaux de compilation. AprĂšs la compilation, nous avons besoin des fichiers de sortie suivants:

  • u-boot-ivt.img
  • u-boot-ivt.img.log
  • SPL
  • SPL.log

copiez-les dans $ {CST_PATH} / release / linux64 / bin. Ensuite, vous devez exécuter un script assez simple.

Description détaillée de la procédure de script
(*.csf). , :

  • .

. , ( ).

:

Image Name:   U-Boot 2019 //  U-boot
Created:      XXXXXX
Image Type:   ARM U-Boot Firmware with HABv4 IVT (uncompressed)
Data Size:    339904 Bytes = 331.94 KiB = 0.32 MiB
Load Address: 17800000
Entry Point:  00000000
HAB Blocks:   0x177fffc0   0x0000   0x00051020

Image Type:   Freescale IMX Boot Image //  SPL
Image Ver:    2 (i.MX53/6/7 compatible)
Mode:         DCD
Data Size:    61440 Bytes = 60.00 KiB = 0.06 MiB
Load Address: 00907420
Entry Point:  00908000
HAB Blocks:   00907400 00000000 0000cc00
DCD Blocks:   00910000 0000002c 00000004

«HAB Blocks». ,

cd ${CST_PATH}/release/linux64/bin
./cst --o u-boot_csf.bin --i u-boot.csf
cat u-boot-ivt.img u-boot_csf.bin > u-boot_signed.img


Pour autant que je me souvienne dans le cas du SPL intĂ©grĂ©, tout fonctionnera probablement de la mĂȘme maniĂšre, mais cela vaut la peine de le vĂ©rifier. Je ne me souviens pas maintenant et je n'ai pas commencĂ© Ă  compiler lors de la rĂ©daction de cet article.

cd ${CST_PATH}/release/linux64/bin
SOC=mx6 ./var-som_sign_image.sh SPL u-boot-ivt.img

Selon les rĂ©sultats du script, vous obtiendrez deux fichiers: SPL_signed, u-boot-ivt.img_signed, qui doivent ĂȘtre Ă©crits sur le disque du systĂšme cible. J'applique un exemple de script d'enregistrement au systĂšme cible. Sans sudo, pour ne pas vous tirer accidentellement dans la jambe.

dd if=SPL_signed of=${DEVICE(/dev/sd*)} bs=1K seek=1; sync
dd if=u-boot-ivt.img_signed of=${DEVICE(/dev/sd*)} bs=1K seek=69; sync

AprÚs avoir écrit sur un support vierge, vous devriez obtenir un chargeur de démarrage sans noyau qui tombera en panne dans la console, car il ne trouvera pas dtb et le noyau. Dans la console, vous pouvez vérifier si ce que vous avez fait ou non fonctionne vraiment. En présence d'un événement - quelque chose s'est mal passé. Important: si le chargeur de démarrage est compilé sans prise en charge HAB, il n'y aura pas non plus d'erreurs.

hab_status
HAB Configuration: 0xf0, HAB State: 0x66
No HAB Events Found!

La derniĂšre Ă©tape consiste Ă  activer le HAB, l'attention est une commande unique, elle ne peut pas ĂȘtre corrigĂ©e, alors soyez prudent

fuse prog 0 6 0x2

Conclusion


Je n'ai pas commencé à décrire le processus d'intégration de tout cela dans yocto, mais je dois garder des secrets. Cependant, cela est faisable et ne nécessite pas beaucoup de temps.

référence


[1] logiciel embarqué sur du métal nu qui s'exécute directement sur le matériel sans aucune abstraction sous forme de systÚmes d'exploitation
[2] we.easyelectronics.ru/Soft/zaschita-ustroystva-ot-vzloma-i-kopirovaniya.html
[3 ] habr.com/en/post/350602
[4] HAB4_API.pdf Ă  github.com/BMValeev/CST_TOOL
[5] variwiki.com/index.php?title=High_Assurance_Boot
[6] boundarydevices.com/high-assurance-boot -hab-dummies
[7] github.com/BMValeev/CST_TOOL

All Articles