Academiejaar 2005 - 2006
Departement Industriële Wetenschappen BME - CTL
Schoonmeersstraat 52 - 9000 Gent
Eindwerk voorgedragen tot het behalen van het diploma van INDUSTRIEEL INGENIEUR INFORMATICA
Karel NIJS Promotoren: Dhr. Joachim VAN MEIRVENNE Dhr. Erwin DEUMENS (IMEC Heverlee, Leuven) Dhr. Kristof LOOTS (IMEC Heverlee, Leuven)
Academiejaar 2005 - 2006
Departement Industriële Wetenschappen BME - CTL
Schoonmeersstraat 52 - 9000 Gent
Eindwerk voorgedragen tot het behalen van het diploma van INDUSTRIEEL INGENIEUR INFORMATICA
Karel NIJS Promotoren: Dhr. Joachim VAN MEIRVENNE Dhr. Erwin DEUMENS (IMEC Heverlee, Leuven) Dhr. Kristof LOOTS (IMEC Heverlee, Leuven)
Karel Nijs
Automatisatie van ASIC vericatie
Copyright 2005, 2006 Karel Nijs
[email protected] http://www.karelnijs.be
Alle rechten voorbehouden.
Dit werk mag worden verveelvoudigd en/of openbaar gemaakt door middel van
druk, fotokopie, microlm, geluidsband, kleitabletten, elektronische of welke andere wijze ook, onder de volgende voorwaarden:
•
Vermelding van de auteur.
•
Commerciëel gebruik is niet toegelaten.
•
Als je dit werk wijzigt en/of verdeelt, moet dit gebeuren onder dezelfde voorwaarden.
De auteur is niet aansprakelijk voor eventuele fouten en onvolledigheden in dit werk.
Versie 1.0 Gecompileerd op: 9 mei 2006
1
Woord vooraf Dit eindwerk is geschreven voor het behalen van het diploma Industrieel Ingenieur Informatica aan de Hogeschool Gent, Departement Industriële Wetenschappen BME-CTL, te Gent.
De tekst zelf is geschreven op het GNU/Linux platform met LATEX en afgedrukt bij IMEC. Ik heb geprobeerd een zo goed mogelijk beeld te geven van de ontwikkeling van dit eindwerk, alsook de geslaagde en mislukte dingen. Van een eindwerk moet je iets bijleren en dat heb ik ook gedaan. Deze tekst is waarschijnlijk niet foutloos. Daarom zou ik me willen excuseren voor mogelijke fouten. Graag wil ik volgende mensen nog even bedanken:
•
Mijn ouders die met de kans gegevens hebben deze opleiding te volgen en me hierin altijd gesteund hebben.
•
Mijn vriendin, Wendy De Zutter, voor het nalezen van de tekst en steun gedurende het hele jaar (en meer).
•
Joachim Van Meirvenne, docent Netwerkprogrammatie aan de Hogeschool Gent en interne promotor van dit eindwerk, voor begeleiding bij de ontwikkeling en ideeën wanneer ik even niet verder kon.
•
Mijn externe promotors, Erwin Deumens en Kristof Loots, voor de begeleiding en het vertrouwen in mij, het hele jaar lang.
•
De FOSDEM mensen: Clif Flynt voor de unieke kans die ik kreeg om te spreken op FOSDEM. Philip Vanmontfort, Kenny Dendauw-Imbo, de gebroeders Demeyer en Bart Derycke voor het aanwezig zijn tijdens deze presentatie.
Verder nog dank aan alle mensen die ik vergeten ben.
Karel Nijs Gent, 9 Mei 2006
2
Inhoudsopgave L¼st van guren
vi
L¼st van tabellen
vii
Lijst van afkortingen
x
I Inleiding
1
1 Inleiding
2
2 Huidige situatie en probleemstelling
5
1.1 1.2
2.1 2.2 2.3 2.4
2.5
2.6
Stage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Eindwerk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.1 Opdracht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Terminologie . . . . . . . . . . . . . . . . . . . . . . . . . . Productieproces . . . . . . . . . . . . . . . . . . . . . . . . . Probleemstelling . . . . . . . . . . . . . . . . . . . . . . . . Doelstellingen . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.1 Doelstellingen van IMEC . . . . . . . . . . . . . . . 2.4.2 Extra doelstellingen (promotor Hogeschool Gent) . . 2.4.3 Overzicht mogelijke opties en uitbreidingen . . . . . Controleren van een GDS-le aan de hand van een rules le 2.5.1 Vooraf . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.2 Controle zelf . . . . . . . . . . . . . . . . . . . . . . 2.5.3 Uitvoer . . . . . . . . . . . . . . . . . . . . . . . . . Uitvoeren van een check met Calibre . . . . . . . . . . . . . 2.6.1 Verschillende stappen . . . . . . . . . . . . . . . . . 2.6.2 Besluit . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
3 3 3
5 6 6 8 8 8 8 9 9 9 10 10 10 11
II GUI
13
3 Tcl/Tk GUI
14
3.1
Vooraf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 Tcl/Tk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.2 Tcl uitbreidingen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
i
14 14 15
Karel Nijs
3.2 3.3
3.4
3.5 3.6
3.1.3 Tix . . . . . . . . . . . . . . . . . . . . . Keuze van opslagstructuur GDS-les . . . . . . Tcl main GUI . . . . . . . . . . . . . . . . . . . 3.3.1 Conguratie van GUI . . . . . . . . . . 3.3.2 Listboxen voor selectie van specicaties Uitvoering checks . . . . . . . . . . . . . . . . . 3.4.1 Command line options . . . . . . . . . . 3.4.2 Editeren rules le . . . . . . . . . . . . . 3.4.3 Wachtrij . . . . . . . . . . . . . . . . . . 3.4.4 Check monitoring . . . . . . . . . . . . . 3.4.5 Annuleren van checks . . . . . . . . . . Foutafhandeling . . . . . . . . . . . . . . . . . . Codedocumentatie . . . . . . . . . . . . . . . .
4 EDA speciek 4.1
4.2
Automatisatie van ASIC vericatie
Calibre . . . . . . . . . . 4.1.1 Rules le . . . . 4.1.2 Executie . . . . . 4.1.3 Rapportgeneratie 4.1.4 Clean up . . . . Dracula . . . . . . . . . 4.2.1 Rules le . . . . 4.2.2 Executie . . . . . 4.2.3 Rapportgeneratie 4.2.4 Clean up . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
16 16 17 18 19 22 22 22 23 27 29 29 30
32
32 32 33 34 35 35 35 36 37 37
III Netwerklaag
39
5 Netwerklaag: algemeen en beveiliging
40
5.1 5.2
5.3
5.4
5.5
Inleiding . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 Situtatieschets . . . . . . . . . . . . . . . . . . Remote execution met SSH . . . . . . . . . . . . . . . 5.2.1 Oplossingen voor interactief inloggen met SSH 5.2.2 Problemen bij SSH executie . . . . . . . . . . . 5.2.3 Signalen opvangen . . . . . . . . . . . . . . . . Remote executie via een C service . . . . . . . . . . . . 5.3.1 Uitvoeren via een C module met rexec() . . . 5.3.2 Uitvoeren via aangemaakt script . . . . . . . . 5.3.3 Besluit . . . . . . . . . . . . . . . . . . . . . . . Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4.1 Plaats in OSI-model . . . . . . . . . . . . . . . 5.4.2 Verschillende statussen . . . . . . . . . . . . . . 5.4.3 Sequentienummers . . . . . . . . . . . . . . . . Beveiliging . . . . . . . . . . . . . . . . . . . . . . . . . 5.5.1 Vooraf . . . . . . . . . . . . . . . . . . . . . . .
ii
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
40 40 42 43 43 46 46 47 47 48 49 49 50 52 53 53
Karel Nijs
5.5.2 5.5.3 5.5.4 5.5.5 5.5.6 5.5.7
Automatisatie van ASIC vericatie
Doorgeven commando's van de Tcl GUI naar de Tcl C extensie Verkeer tussen client en server . . . . . . . . . . . . . . . . . . . Server service op poort x . . . . . . . . . . . . . . . . . . . . . . Uitvoeren van commando's . . . . . . . . . . . . . . . . . . . . Output van commando's . . . . . . . . . . . . . . . . . . . . . . Uitvoeromgeving . . . . . . . . . . . . . . . . . . . . . . . . . .
6 Netwerklaag: implementatie 6.1
6.2 6.3
6.4 6.5
6.6
6.7 6.8
Inleiding . . . . . . . . . . . . . . . . . . . 6.1.1 IDE . . . . . . . . . . . . . . . . . 6.1.2 C++ debuggen . . . . . . . . . . . 6.1.3 Geheugenfouten en -lekken . . . . 6.1.4 HP-UX compilatie . . . . . . . . . 6.1.5 API . . . . . . . . . . . . . . . . . Namespaces en utilities . . . . . . . . . . . Klassenmodel . . . . . . . . . . . . . . . . 6.3.1 Debug klasse . . . . . . . . . . . . 6.3.2 PSgen klasse . . . . . . . . . . . . 6.3.3 Client-server model . . . . . . . . . 6.3.4 Socketlaag van de netwerklaag . . 6.3.5 ASICproto laag van de netwerklaag Client . . . . . . . . . . . . . . . . . . . . 6.4.1 ASICclient . . . . . . . . . . . . . Listener . . . . . . . . . . . . . . . . . . . 6.5.1 Aanmaken luisteraar . . . . . . . . 6.5.2 Conguratie luisteraar . . . . . . . 6.5.3 Concurrent server . . . . . . . . . . 6.5.4 Bijhouden clients . . . . . . . . . . 6.5.5 Afhandelen clients . . . . . . . . . 6.5.6 Opkuisen clients . . . . . . . . . . ASICserver . . . . . . . . . . . . . . . . . 6.6.1 startup() . . . . . . . . . . . . . . 6.6.2 recv_msg() . . . . . . . . . . . . . 6.6.3 exec_cmd() . . . . . . . . . . . . . 6.6.4 kill_process() . . . . . . . . . . . . 6.6.5 server_info() . . . . . . . . . . . . 6.6.6 send_pid_exists() . . . . . . . . . Server . . . . . . . . . . . . . . . . . . . . 6.7.1 Opstarten server service . . . . . . Samenwerking met de GUI . . . . . . . . . 6.8.1 Tcl C extensie . . . . . . . . . . . . 6.8.2 Berichten doorgeven . . . . . . . . 6.8.3 Foutmeldingen . . . . . . . . . . . 6.8.4 Opstarten GUI . . . . . . . . . . .
iii
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53 56 58 59 59 59
62
62 62 62 63 63 64 64 66 66 66 67 67 69 70 70 73 73 74 74 75 77 78 80 80 80 81 87 87 88 88 88 89 89 90 90 92
Karel Nijs
7 SSL implementatie 7.1
7.2
7.3
7.4
7.5
7.6
SSL Algemeen . . . . . . . . . . . . . 7.1.1 SSL of TLS . . . . . . . . . . 7.1.2 SSL API . . . . . . . . . . . . 7.1.3 SSL cryptograe . . . . . . . Certicaten . . . . . . . . . . . . . . 7.2.1 Root certicatie authoriteit . 7.2.2 Generatie certicaat . . . . . SSLfunctions utility namespace . . 7.3.1 SSLfunctions::SSL_write() 7.3.2 SSLfunctions::SSL_read() . 7.3.3 Certicaat controle . . . . . . Client . . . . . . . . . . . . . . . . . 7.4.1 SSLconn klasse . . . . . . . . 7.4.2 PlainClient klasse . . . . . . . 7.4.3 SSLclient klasse . . . . . . . . 7.4.4 Contextinitialisatie . . . . . . 7.4.5 Client side session caching . . 7.4.6 close_conn() . . . . . . . . . Server . . . . . . . . . . . . . . . . . 7.5.1 PlainServer klasse . . . . . . 7.5.2 SSLserver klasse . . . . . . . 7.5.3 Server side session caching . . Lessenpakket . . . . . . . . . . . . . 7.6.1 BIO sockets . . . . . . . . . . 7.6.2 Theoretische basis . . . . . . 7.6.3 Toepassingen in real life . . .
Automatisatie van ASIC vericatie
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
95
95 96 97 97 99 99 99 99 99 100 101 102 102 102 102 103 105 107 107 108 108 108 110 110 111 112
8 Besluit
113
Appendices
114
A Flowcharts
115
B Man pages
118
C Installation manual
124
D Rapporten
152
A.1 Editeren rules le . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 A.2 Uitvoeren Calibre check . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 A.3 Check executie wachtrij . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 B.1 runasicgui . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 B.2 runasicserver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
D.1 Calibre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 D.2 Dracula . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
iv
Karel Nijs
Automatisatie van ASIC vericatie
Bibliograe
158
v
L¼st van guren 1.1
Logo's IMEC en EUROPRACTICE
. . . . . . . . . . . . . . . . . . . . . . . . .
2
2.1 2.2
De blauwdruk van een ASIC voor een camera CCD . . . . . . . . . . . . . . . . . Het productieproces bij EuroPractice . . . . . . . . . . . . . . . . . . . . . . . . .
6 7
3.1 3.2 3.3 3.4 3.5 3.6 3.7
Tcl/Tk logo . . . . . . . . . . . . . . . . . . . . . . . . Eén van de redenen om Tix te gebruiken . . . . . . . . Directorystructuur van de beschikbare technologieën . Selectie van de technologie . . . . . . . . . . . . . . . . Wachtrij met individuele starttijd voor de verschillende Rij voor checks in uitvoering . . . . . . . . . . . . . . . Check Monitoring toplevel widget . . . . . . . . . . . .
. . . . . . . . . . . . . . . . checks . . . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
14 16 17 20 23 25 28
5.1 5.2 5.3 5.4 5.5
Vereenvoudigd proces van remote execution . . . . . . Plaats van de netwerklaag in het n-tier model . . . . . Plaats van het onbeveiligde protocol in het OSI-model Plaats van het beveiligde protocol in het OSI-model . Verschillende statussen van asicPROTO . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
41 48 50 50 61
6.1 6.2 6.3 6.4 6.5 6.6
IConnection abstracte klasse . . . . . . . Mogelijke implementatie van CryptConn ASIChost abstracte klasse . . . . . . . . ASICclient klasse . . . . . . . . . . . . . Uitvoermodel concurrent server . . . . . ASICserver object model . . . . . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
68 69 70 71 74 80
. . . . klasse . . . . . . . . . . . . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
A.1 De gebeurtenis bij een klik op de Edit knop voor elke check . . . . . . . . . . . . 115 A.2 De rules le controle voor een calibre check . . . . . . . . . . . . . . . . . . . . . 116 A.3 De werking van de check executie wachtrij . . . . . . . . . . . . . . . . . . . . . . 117
vi
L¼st van tabellen 3.1 3.2 3.3
Globale Tcl variabelen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Check statussen in de wachtrij . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Verschillende loglevels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26 26 30
4.1
Dracula output les
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
5.1
Protocolberichten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
51
6.1
Positionering commando's in ::nw_service::my_socket commando . . . . . . .
89
7.1
Opties voor cipher keuze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
vii
Lijst van Codefragmenten 3.1 3.2 4.1 4.2 5.1 5.2 5.3 5.4 5.5 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 6.10 6.11 6.12 6.13 6.14 6.15 6.16 6.17 6.18 6.19 6.20 6.21 7.1 7.2 7.3 7.4 7.5 7.6
eval sleutelwoord vereist . . . . . . . . . . . . . . . . . . . . Datastructuur voor keuzelijstgeneratie . . . . . . . . . . . . . PDRACULA input le . . . . . . . . . . . . . . . . . . . . . . Volledig Dracula commando . . . . . . . . . . . . . . . . . . . Vereenvoudigd voorbeeld van opstarten remote proces . . . . Controleren via SSH of remote PID bestaat . . . . . . . . . . SSH uitvoering met Perl wrapper . . . . . . . . . . . . . . . . Opbouw Calibre commando met SSH . . . . . . . . . . . . . . Valideren handtekening bij opstarten applicatie (pseudocode) Traditionele foutafhandeling . . . . . . . . . . . . . . . . . . . Foutafhandeling volgens ons Debug model . . . . . . . . . . . Networkfunctions::Gethostbyname() functie . . . . . . . . . . Gebruik syslog() . . . . . . . . . . . . . . . . . . . . . . . . . Gebruik van abstracte klasse IConnection . . . . . . . . . . . ASICproto bericht . . . . . . . . . . . . . . . . . . . . . . . . Gebruik van de ASICclient klasse . . . . . . . . . . . . . . . . Eciënt gebruik van een PIPE_BUF grote buer . . . . . . . . Annulatie bericht . . . . . . . . . . . . . . . . . . . . . . . . . Aggressief sluiten socket . . . . . . . . . . . . . . . . . . . . . Instellen socket opties . . . . . . . . . . . . . . . . . . . . . . Correct afsluiten socket . . . . . . . . . . . . . . . . . . . . . Listener::getFreePosition() . . . . . . . . . . . . . . . . . . . . Conguratie van thread mutexen . . . . . . . . . . . . . . . . Ontvangen van clients en thread mutexen . . . . . . . . . . . ASICserver: Uitvoeren commando's in pseudocode . . . . . . Executioner: Uitvoeren commando in pseudocode . . . . . . . De kill_proces() functie . . . . . . . . . . . . . . . . . . . . Tcl aanroep van ::nw_service::my_socket . . . . . . . . . . Foutopvanging en foutberichtgeneratie . . . . . . . . . . . . . Het runasicgui programma . . . . . . . . . . . . . . . . . . . Keuze ciphers . . . . . . . . . . . . . . . . . . . . . . . . . . . Beschikbare ciphers . . . . . . . . . . . . . . . . . . . . . . . . Instellen ciphers . . . . . . . . . . . . . . . . . . . . . . . . . . read() met timeout . . . . . . . . . . . . . . . . . . . . . . . SSLclient::open_conn() pseudocode . . . . . . . . . . . . . Instellen password callback functie . . . . . . . . . . . . . . .
viii
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. 19 . 20 . 36 . 36 . 43 . 44 . 45 . 46 . 56 . 64 . 65 . 65 . 66 . 67 . 69 . 70 . 72 . 73 . 75 . 75 . 76 . 78 . 79 . 79 . 83 . 85 . 87 . 90 . 91 . 93 . 97 . 98 . 98 . 100 . 103 . 104
Karel Nijs
7.7 7.8 7.9 7.10 D.1 D.2
Automatisatie van ASIC vericatie
SSL client side session caching . . . . . Sluiten SSL verbinding . . . . . . . . . SSLserver::open_conn() pseudocode Client met SSL BIO sockets . . . . . . Ingekort Calibre rapport . . . . . . . . Dracula rapport . . . . . . . . . . . . .
ix
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
105 107 109 110 153 156
Lijst van afkortingen API
Application Program Interface
ASIC
Application Specic Integrated Circuits
DoS
Denial Of Service
DSA
Digital Signature Algorithm
EDA
Electronic Design Automation
EOC
End Of Communication
EOF
End Of File
FIFO
First In First Out
FOSDEM
Free & Open Software Developers Meeting
GUI
Graphical User Interface
HTML
HyperText Markup Language
IETF
Internet Engineering Task Force
IPsec
Internet Protocol Security
MAC
Message Authentication Code
OSI
Open Systems Interconnection
PID
Process IDentier
POSIX
Portable Operating-System Interface for uniX
SSH
Secure Shell
SSL
Secure Socket Layer
TLS
Transport Layer Security
x
Deel I
Inleiding
1
Hoofdstuk 1
Inleiding Ik ben Karel Nijs en studeer momenteel voor Industrieel Ingenieur Informatica (III) student aan de Hogeschool Gent, te Gent. Ik programmeer graag en probeer zo veel mogelijk met vrije software te werken. Zo gebruik ik altijd het GNU/Linux besturingssysteem, het OpenOce pakket en programmeer het liefst in Java, C++ en PHP. Ik heb voor een eindwerk bij IMEC gekozen omdat de uitdaging om een nieuwe (programmeer)taal te leren in deze stimulerende omgeving wel zag zitten.
(a) IMEC
Figuur 1.1:
(b) EuroPractice
Logo's IMEC en EUROPRACTICE
IMEC staat voor Interuniversitair Micro-Elektronica Centrum en is een onderzoekscentrum voor moderne micro-elektronica en aanverwante domeinen. IMEC bestaat uit verschillende afdelingen met specialisaties gaande van fundamenteel onderzoek tot productie en training. Mijn stage en eindwerk gaan door bij de Industrile Vorming Micro-Electronica (INVOMEC) afdeling van IMEC. EUROPRACTICE is een prototype service voor micro-elektronica die bestaat uit de samenwerking tussen RAL, FHG en INVOMEC. EUROPRACTICE wordt gecoördineerd door INVOMEC.
2
Karel Nijs
Automatisatie van ASIC vericatie
Tijdens de ontwikkeling van deze applicatie voor EUROPRACTICE, werd ik door twee IMEC'ers bijgestaan: Kristof Loots en Erwin Deumens. Kristof heeft me op weg geholpen met de software, terwijl Erwin me het elektronica jargon heeft verklaard en de ontwikkeling van de GUI opvolgt. Op 25 februari 2006 heb ik de kans gehad om mijn eindwerk te presenteren op de FOSDEM meeting op de Vrije Universiteit Brussel, te Brussel. Ik heb deze mogelijkheid aangeboden gekregen van Clif Flynt, één van de schrijvers van de uitgebreide Tcl documentatie (zie (4)), na een ontmoeting op de nieuwsgroep comp.lang.tcl. Omdat het mij een unieke kans leek, heb ik deze met open armen aangenomen. De slides van de presentatie zijn beschikbaar op de bijgeleverde CD-ROM.
1.1 Stage Bij dit eindwerk was een stage van drie maanden voorzien. Ik heb deze periode mogen inkorten tot zes weken omdat ik al ervaring met het *nix besturingssysteem had. Tijdens mijn stage heb ik voornamelijk de Tcl/Tk programmeertaal aangeleerd, de EDA-software leren gebruiken en de mengelmoes van bestaande controlescripts geanalyseerd.
1.2 Eindwerk 1.2.1 Opdracht Een ASIC is een micro-elektronica chip speciaal ontworpen voor bepaalde applicaties. In het kader van EUROPRACTICE biedt IMEC een prototype service aan voor ASIC's. Als een klant een idee heeft voor een bepaalde toepassing kan hij dit laten uitwerken tot een GDSle bij IMEC of zelf een GDS-le maken en naar IMEC sturen. Een GDS-le is een blauwdruk voor een ASIC. Voor men de productie van een chip kan starten, moet eerst deze blauwdruk gecontroleerd worden. Dit gebeurt aan de hand van een rules le. Deze rules le wordt door de uiteindelijke (externe) fabrikant van de chip geleverd. Hierna wordt de GDS-le gecontroleerd aan de hand van de aangepaste rules le. De controle gebeurt met verschillende software pakketten (EDA's) en moet handmatig opgestart worden. Zo'n controle van een ASIC kan 2 uur tot 2 dagen duren en is processorintensief voor de servers die de software moeten draaien. Zo kunnen er voor één ASIC verschillende checks opgestart worden. Bij het vinden van fouten moet de GDS-le door de klant aangepast worden en opnieuw worden gecontroleerd.
3
Karel Nijs
Automatisatie van ASIC vericatie
De bedoeling van het eindwerk is dit hele proces te automatiseren en te stroomlijnen door er een grasche user interface voor te ontwikkelen.
4
Hoofdstuk 2
Huidige situatie en probleemstelling Om de ontwikkeling van het project nader te verklaren, zullen we eerst de huidige situatie uitleggen. De productie en vericatie van een ASIC is een ingewikkeld proces en om de verdere tekst te begrijpen, is het noodzakelijk een blik te werpen op dit productieproces.
2.1 Terminologie ASIC Een Application Specic Integrated Circuits is een chip (IC) geschikt om een bepaalde taak.
Foundry Een Foundry is een bedrijf dat (elektronica)chips produceert, bv. Philips. FAB Een FAB is de fabriek zelf waar geproduceert worde. Een typische Foundry heeft meerdere FAB's, bv. Philips Brussel.
GDS-le Een GDS-le is een blauwdruk voor de productie van een ASIC. rules le Een rules le bevat de regels waaraan de blauwdruk van een ASIC moet voldoen. Zo is er bijvoorbeeld een regel dat je maar x nanometer tussen twee transistoren mag hebben.
EDA Een Electronic Design Automation is software om chips mee te ontwerpen. Enkele voorbeelden: Calibre (Cadence), Dracula (Mentor), Hercules (Cadence), . . .
check Een check of controle gaat de GDS-le controleren aan de hand van een rules le. CIF database Een resultaat database. rapport le Een rapport dat aan de klanten gegeven wordt na een uitgevoerde check. Een EDA kan meerdere soorten checks uitvoeren. Zo kunnen er bijvoorbeeld met Calibre DRC en ERC checks uitgevoerd worden. Voor elke EDA heb je een andere rules le nodig.
5
Karel Nijs
Automatisatie van ASIC vericatie
2.2 Productieproces
Figuur 2.1:
De blauwdruk van een ASIC voor een camera CCD
Wanneer een klant bijvoorbeeld een chip hebben, geschikt voor een bepaald type GSM, maakt ofwel de klant de blauwdruk voor deze ASIC, ofwel geeft de klant opdracht aan EuroPratice voor het maken van deze blauwdruk. Vervolgens moet deze blauwdruk gecontroleerd worden op fouten vooraleer tot productie over gegaan kan worden. Dit is de taak van EuroPractice en gebeurt aan de hand van rules les voor een bepaalde technologie, bv. CMOS 0.8 µm. Deze rules le wordt geleverd door de Foundry zelf. Wanneer de GDS-le foutvrij en productieklaar is, wordt ze gegeven aan een FAB van de Foundry en zorgt deze FAB voor de productie.
2.3 Probleemstelling De GUI moet zo intuïtief mogelijk ontworpen zijn en makkelijk te gebruiken. Het is de bedoeling dat de hele EUROPRACTICE afdeling in IMEC er checks mee gaat uitvoeren. Er moet een analyse gebeuren van de huidige scripts (een mengeling van C-shell, Perl, sed, awk en command line) en de EDA-software zodat er eerst handmatige checks opgestart kunnen wor-
6
Karel Nijs
Automatisatie van ASIC vericatie
Figuur 2.2:
Het productieproces bij EuroPractice
den. Deze checks moeten vervolgens geautomatiseerd worden door bediening via een grasche interface. Ook zijn de checks belastend voor de servers en moet de mogelijkheid onderzocht worden of de checks op verschillende servers remote en met een bepaalde uitsteltijd (delay) kunnen opgestart worden. Het is voor IMEC vereist dat de GUI in Tcl/Tk ontworpen wordt. Omdat de keuze van de taal voor mij genomen is, zal ik onderzoeken wat de gekende voor- en nadelen van deze taal zijn en hoe deze te gebruiken/omzeilen. Het is belangrijk voor IMEC zo weinig mogelijk extra software te installeren. Door deze keuzes zijn we eventueel verplicht om eigen Tcl/Tk uitbreidingsmodules te ontwerpen in ANSI C. Om de commando's door te sturen naar de server moet er een protocol ontworpen worden die de communicatie beschrijft. Omdat de server remote commando's gaat uitvoeren, is de beveiliging van deze applicatie een kritiek punt: niet iedereen mag zomaar commando's sturen naar de server in de hoop dat ze uitgevoerd zullen worden.
7
Karel Nijs
Automatisatie van ASIC vericatie
2.4 Doelstellingen 2.4.1 Doelstellingen van IMEC • Voor IMEC is het belangrijk dat de applicatie op het einde van het jaar werkt en bruikklaar is. • De GUI moet zo dynamisch mogelijk zijn zodat er later geen aanpassingen vereist zijn wanneer er een nieuwe Foundry of Technology toegevoegd wordt. • Er moet een mogelijkheid zijn om het resultaat van een check te bekijken (rapport) en eventueel dit rapport zelf te genereren. • De GUI en logica moet in één programmeertaal geschreven worden, namelijk Tcl/Tk. Omdat de gebruikte EDA-software enkel op GNU/Linux of Unix (HP-UX) kunnen uitgevoerd worden, is het vereist dat de GUI *nix compatibel is. • Om versieconicten en/of niet-beschikbaarheid van modules in softwarepakketten te vermijden, wilt IMEC dat er zo weinig mogelijk andere software geïnstalleerd wordt. Op deze manier komen ze niet in de problemen met te-onderhouden licenties en updates. • De GUI moet zo intuïtief mogelijk zijn: nieuwe gebruikers moeten de interface kunnen gebruiken zonder hulp1 . • De broncode moet goed gedocumenteerd worden en er moet zoveel mogelijk met modules gewerkt geworden zodat de applicatie later makkelijk aanpasbaar is.
2.4.2 Extra doelstellingen (promotor Hogeschool Gent) • De communicatie tussen client en server moet volgens een zelf ontworpen protocol gebeuren. • De beveiliging van deze communicatie moet bestudeerd en geïmplementeerd worden.
2.4.3 Overzicht mogelijke opties en uitbreidingen Omdat de analyse en implementatie van de huidige werking van checks nogal ingewikkeld is, verwacht IMEC dat ik hier een tijdje bezig mee zal zijn. Daarom hebben ze volgende uitbreidingen voorgesteld: 1. Delayed start: checks opstarten na een bepaald uur om de workload van de servers te verlichten. 2. Remote Execution van de checks: de GUI lokaal opstarten, maar de check op een server uitvoeren. 3. Distributed checks opstarten: de check verspreiden over verschillende servers. 1
Er moet natuurlijk wel minimale kennis van het hele gebeuren zijn.
8
Karel Nijs
Automatisatie van ASIC vericatie
4. Update van EDA-software mogelijk maken. 5. Module voor het inscannen van de topcell van een GDS-le met de GScan software. Alle uitbreidingen zijn opgenomen in mijn eindwerk. Van mijn interne promotor hebben we volgende uitbreidingen gekregen (ook: zie boven): 1. Een eigen communicatie protocol ontwerpen. 2. De client-server communicatie beveiligen.
2.5 Controleren van een GDS-le aan de hand van een rules le Het hele proces wat nu ga beschreven wordt, is sterk verschillend voor elke EDA.
2.5.1 Vooraf Voor de productie van een ASIC moet hij eerst getest worden. Dit gebeurt met een EDA, bv. Dracula. Tijdens de test worden de opgemeten waarden, genomen uit de GDS-le, vergeleken met deze in de rules le. De test software is al (centraal) geïnstalleerd. De rules le, geleverd door de klant (dit kan een zowel afdeling van IMEC zijn als een externe klant), ondergaat een kleine toevoeging van IMEC-gegevens. Alle rules les staan in een speciek geordende directorystructuur; de GDS-les staan op willekeurige plaatsen.
2.5.2 Controle zelf IMEC krijgt een zip-le opgestuurd door de klant met hierin de GDS- en andere les (niet van belang hier). Om de GDS-le te testen, zijn van belang: a) de Foundry, bv. AMIS; b) de Technology, bv. 0,7µm; c) de Options, bv. CMOS 7B. Vervolgens moet er gekozen worden welk check uitgevoerd wordt. Hier is van belang: d) het type check, bv. DRC; e) de EDA-software, bv. Dracula.
9
Karel Nijs
Automatisatie van ASIC vericatie
Uit de GDS-le (of eventueel de rules le) wordt de topcell (f) gehaald. Met de combinatie {a, b, c, d, e, f} kan je de correcte rules le vinden om te vergelijken/testen met de GDS-le. Opmerkingen: 1.
al deze opties mogen in een cong-le bijgehouden worden voor verdere checks,
2. een GDS-le kan meerdere topcells bevatten. In de rules le wordt de naam van de GDS-le bestaand script van IMEC.
en topcell automatisch ingevuld door een al
2.5.3 Uitvoer De uitvoer van het commando komt terecht in de directory waar het commando uitgevoerd wordt en resulteert in een directory die de naam van de check heeft, bv. DRC. Deze directory wordt door het controle script zelf aangemaakt en bevat menige output les, oa. het rapport, de resultaatdatabase, . . . Na een gelukte of mislukte check wordt, eens de rapporten verwerkt zijn, deze directory weer opgekuist.
2.6 Uitvoeren van een check met Calibre Deze sectie beschrijft het in zijn werk gaan van het eectief uitvoeren van een check. Als voorbeeld voeren we een DRC check uit van een UMC18g2 met Calibre als EDA.
2.6.1 Verschillende stappen Stap 1 De check kan in eender welke directory opgestart worden. Wanneer er bv. een DRC check uitgevoerd gaat worden, maakt men hier eerst een speciale directory voor aan zodat alle resulterende les van de check (een vijftal) hierin geplaatst worden.
Stap 2 Vervolgens wordt de check opgestart met een hiervoor speciaal ontworpen script (geschreven in C-shell code). Merk op dat er nog altijd geen parameters (Foundry, Technology, . . . ) of het type check zelf meegegeven zijn (de zo juist aangemaakte map mag eigenlijk eender welke naam hebben). 1
$ /imec/other/invosoft/Software/dracula/COM/cali
10
Karel Nijs
Automatisatie van ASIC vericatie
Opmerkingen: 1. Je moet dit script uitvoeren in de directory DRC want de paden zijn hard gecodeerd. 2. Er is een
gelijkaardig script voor checks met Dracula enz.
Stap 3 Wanneer het cali script start, moet je enkele parameters opgeven. Veel van deze parameters zijn hard gecodeerd en er is hier geen vrijheid in. Ook padverwijzingen naar bronles zijn reeds (half) aanwezig in de broncode. Toevoegen/wijzigen van parameters vereist een aanpassing van het script. Volgende parameters moet je ingeven:
• de technology (ineens een combinatie van Foundry, Technology en Options), • (de locatie van) de GDS-le, • een extra parameter die ontstaan is door de combinatie DRC en Calibre, • de naam van de topcell. Het cali script vult dynamisch de parameters (topcell, locatie GDS-le, ...) in de en voert Calibre uit.
rules le in
Stap 4 Wanneer het programma de check uitvoert, wordt er enige informatie naar het scherm gestuurd (waarmee niets gedaan wordt). Na het voltooien van de check is de directory gevuld met enkele les.
Stap 5 De voorlopig aangemaakte (aangepaste) rules le wordt verwijderd en er wordt vervolgens nog een Perl-script opgeroepen die een rapport en CIF-database genereren.
2.6.2 Besluit Het is de aandachtige lezer misschien al opgevallen dat dit een ingewikkeld proces is. Dit is echter nog maar één EDA die we hier besproken hebben. Er zijn er zo drie. De automatisering van dit hele proces brengt verschillende voordelen met zich mee:
• unicatie, • duidelijkheid,
11
Karel Nijs
Automatisatie van ASIC vericatie
• modularisatie, • gebruik van beperkt aantal programmeertalen. Vooral het beperkt aantal programmeertalen is een voordeel: wanneer je nu bijvoorbeeld het cali script wilt aanpassen, moet je de C-shell, Perl, sed en awk beheersen. Verder is het originele script ook niet eciënt geprogrammeerd, maar dit is eerder een gevolg van aanpassingen en uitbreidingen door de jaren heen (het cali script dateert van 1999).
12
Deel II
GUI
13
Hoofdstuk 3
Tcl/Tk GUI 3.1 Vooraf 3.1.1 Tcl/Tk Tcl1 is een typeloze, actie geöriënteerde en geïnterpreteerde scripttaal. Als grasche subset wordt standaard Tk gebruikt. Tk sluit zo goed bij Tcl aan, dat algemeen Tcl/Tk gezegd en gebruikt wordt.
Figuur 3.1:
Tcl/Tk logo
Tcl/Tk heeft zijn voor- en nadelen. De voordelen:
• de syntax heeft grote gelijkenis met deze van C(++); • er zijn geen types; • Tcl voorziet een uitgebreide integratie van systeemfuncties, string- en lijstbehandeling; • je kan herhaaldelijk commando's in commando's plaatsen; • een eenvoudige GUI is snel gebouwd met behulp van Tk; 1
Spreek uit "Tickle"
14
Karel Nijs
Automatisatie van ASIC vericatie
• we kunnen variabelen gebruiken door variabelenamen te evalueren2 ; • voor niet-programmeurs is dit een ideale instaptaal; • je kan Tcl zelf uitbreiden door of bestaande uitbreidingen te installeren, of er zelf een te schrijven in C(++). Enkele nadelen:
• we beschikken niet over dezelfde mogelijkheden als C++; • er zijn geen types (dit is zowel een voor- als nadeel); • de standaard grasche subset is te beperkt voor wat we tegenwoordig gewoon zijn3 ; • om gebruik te maken van variabelenevaluatie moet je soms trukjes uithalen; • er is geen standaard objectmodel ondersteund (TclOO extensie of andere vereist); • Tcl is zeer syntaxgevoelig: er zijn geen open accolades toegelaten in commentaar, verplichte spaties tussen sleutelwoorden, . . . ; • Tcl voorziet geen foutopvanging zoals Java en C++, maar we kunnen wel met een gewijzigd foutafhandelingsmodel aan de slag; • geen meerdimensionale array's (zie Tabel 3.1). Meer informatie kan je vinden op http://www.tcl.tk/about/.
3.1.2 Tcl uitbreidingen Tcl laat toe dat je de mogelijkheden uitbreidt met extensies. Extensies zijn packages die je op het Internet (eventueel vrij) kan downloaden en lokaal moet installeren. Vervolgens kan je deze gebruiken in het programma mbv. de package require statement. Bij de aanvang van het eindwerk werd me opgelegd geen extra software te installeren en enkel gebruik te maken van de, op de clients, geïnstalleerde Tcl en Tk versies. Ik heb mij zoveel mogelijk proberen te houden aan deze verplichting. Toen de GUI echter te onoverzichtelijk werd, heb ik toestemming gevraagd en gekregen om van de Tix extensie gebruik te maken. Bij nader inzien had ik misschien ook beter wat harder geprobeerd om de TclOO extensie te installeren zodat ik met een objectmodel de Tcl GUI had kunnen ontwerpen. 2 3
JavaScript heeft dezelfde mogelijkheid mbv. de
eval
functie
Er zijn bijvoorbeeld geen uitschuifkeuzelijsten
15
Karel Nijs
Automatisatie van ASIC vericatie
3.1.3 Tix Zoals eerder vermeld is de grasche subset, Tk, beperkt in zijn mogelijkheden. Wanneer we deze zonder de Tix uitbreiding zouden gebruiken, ziet de GUI er uit alsof hij in de jaren '90 gemaakt is.
Figuur 3.2:
Eén van de redenen om Tix te gebruiken
Ook heeft Tk standaard geen tabbladen, comboboxen, "normaal" dialoogvenster, . . . Om dit gebrek te overkomen, hebben we gebruik gemaakt van de Tix extensie. De Tix extensie is standaard geïnstalleerd op alle client PC's bij IMEC, enkel de servers beschikken hier niet over. Dit heeft als rechtstreeks gevolg dat de GUI enkel nog op de clients opgestart kan worden (tenzij natuurlijk de Tix extensie geïnstalleerd wordt op de servers, maar hiervoor heb ik geen toestemming).
3.2 Keuze van opslagstructuur GDS-les De GDS en rules les bevinden zich momenteel in een grote, globaal beschikbare directory waar elke normale gebruiker enkel leesrechten op heeft. Wanneer we vanuit de GUI een technologie willen kiezen, moet het browsen in deze directory via onze GUI even triviaal zijn. Daarom hebben we ervoor gekozen geen ingrijpende veranderingen door te voeren aan de huidige directorystructuur. Momenteel loopt de sortering eerst volgens Foundry, vervolgens moet je de Technology en als laatste de Options kiezen. Wanneer we ons in de Options directory bevinden, hebben we er voor gekozen om een indeling
16
Karel Nijs
Automatisatie van ASIC vericatie
Figuur 3.3:
Directorystructuur van de beschikbare technologieën
te maken volgens type check. In deze directory worden dan de GDS-le(s) geplaatst4 en de rules le(s). Omdat er rules les van een bepaalde check voor verschillende EDA's aanwezig kunnen zijn, spreken we een extensie af waarmee de GUI kan werken. Rules les voor Dracula hebben zo bijvoorbeeld de extensie .drac. In de Options directory kunnen er ook checks niet aanwezig zijn. Als er bijvoorbeeld geen ANT check beschikbaar is, gaat er geen map zijn. Wordt er echter in de conguratie le wél de ANT check vermeld (zie 3.3.1), dan wordt deze in een andere kleur aangeduid in de GUI. Je kan dit duidelijk zien op Figuur 3.4 Op deze manier kan de gebruiker toch een ANT check opstarten met een rules le die zich op een niet-standaard plaats bevindt, ook al is hier geen rules le voor beschikbaar (in de standaard directory). Om toe te laten dat de eindgebruiker een willekeurige check met willekeurige rules le kan uitvoeren, wordt er op Foundry niveau een map, custom, aangemaakt. Wanneer de gebruiker op het Check Settings tabblad een keuze maakt in de uitschuifkeuzelijst van de EDA's wordt in de specieke directory5 met behulp van de bestandsextensie gezocht naar een standaard rules le. Als deze rules le aanwezig is, wordt de gebruiker gevraagd of hij deze niet liever wil gebruiken.
3.3 Tcl main GUI Omdat dit project uit een groot aantal bestanden bestaat, hebben we steeds gewerkt met een aparte indeling. Je kan deze terugvinden in (Engelstalige) installatiehandleiding in Appendix C. 4 5
Soms zijn er meerdere versies Gespecieerd door Foundry, Technology, Options en Check
17
Karel Nijs
Automatisatie van ASIC vericatie
3.3.1 Conguratie van GUI Alle conguratie les bevinden zich in de config directory, in de root van de applicatie.
Applicatie instellingen Tijdens het maken van alle modules, hebben we zoveel mogelijk met namespaces en namespace variabelen gewerkt. De globale variabelen van de Calibre check bevinden zich bijvoorbeeld allemaal in de ::calibre:: namespace van het checks/calibre.tcl bestand. Soms is het echter toch vereist om bepaalde variabelen op applicatieniveau te declareren6 . Voor deze variabelen is er een speciale le, config/application_settings.tcl aangemaakt. Wanneer later het pad naar de Gscan executable zou veranderen7 , kan de beheerder van de project account dit eenvoudig aanpassen in deze le. Wanneer er later tijd over is, of bij verdere opvolging, kan er altijd voor gekozen worden om een aparte administrators interface te ontwerpen om deze instellingen makkelijker toegangbaar te maken.
Gebruiksinstellingen De verschillende checks, EDA's en servers die we willen gebruiken, zijn eigenlijk ook applicatie instellingen. Voor deze instellingen hebben we gekozen om met een plain text conguratie le te werken: deze le gaat namelijk het vaakst bewerkt worden. Wanneer we hier gebruik van zouden maken van een Tcl le, zou de beheerder van de project account lijstvariabelen en andere moeten aanpassen. Omdat Tcl redelijk syntaxgevoelig is, zoals boven vermeld, kan een fout karakter hier de hele GUI niet meer laten opstarten. Wanneer we echter met een tekstueel conguratiebestand werken, gaat enkel de regel waar de fout op staat niet gebruikt kunnen worden. De rest van de le wordt verder verwerkt en de GUI kan zonder problemen opstarten.
Gebruiker sinstellingen De eindgebruiker van de GUI kan beslissen om de instellingen van de GUI op te slaan. Voor een gewone gebruiker is dit niet zo belangrijk, maar speciale gebruikers kunnen met behulp van deze conguratie le exclusieve instellingen deniëren. 6 7
Eigenlijk zitten ze dan nog in een namespace, namelijk de root namespace Software wordt, wanneer mogelijk, centraal geïnstalleerd bij IMEC
18
::
Karel Nijs
Automatisatie van ASIC vericatie
Een voorbeeld hiervan is de ::configfile::turbo optie. Met deze optie kan je checks in turbomodus uitvoeren: beide processoren (als aanwezig) worden dan volledig belast. Dit heeft als gevolg dat de check sneller voltooid is, maar ten koste van de performatie van de server. Wanneer we deze optie voor iedereen beschikbaar zouden stellen, zou iedereen hier ook eectief gebruik van willen maken (niemand wacht graag). Deze situatie wordt nu vermeden met exclusieve instellingen. De conguratie le wordt opgeslagen in de home directory van de gebruiker en stelt laten variabelen in8 .
enkel toege-
Opmaakinstellingen Om de opmaak consistent te houden over de gehele applicatie en ook om deze makkelijk instelbaar te maken, hebben we gewerkt met een aparte stijlconguratie le, style.tcl. Wanneer we nu ergens een lettertype, grootte, kleur, ... gebruiken, gaan we telkens verwijzen naar de (globale) variabelen gedenieerd in deze le. Dit heeft als nadeel dat er nu voor elk commando het eval sleutelwoord moet komen: Tk kan er namelijk niet mee overweg dat je een variabele als optie parsed. Ook moeten er nu meer trukjes uitgehaald worden omdat met het gebruik van eval quotes en accolade's twéémaal geïnterpreteerd worden. 1 2 3 4
% werkt niet label .lbl $::s_label -font ::f_normal_b -text "..." % werkt wel eval label .lbl $::s_label -font ::f_normal_b -text {"..."} Codefragment 3.1:
eval sleutelwoord vereist
Het ene voordeel komt hier samen met een ander nadeel: er is consistentie qua opmaak, maar ten koste van de leesbaarheid van de code.
3.3.2 Listboxen voor selectie van specicaties Om de juiste technologie van de GDS-le te selecteren, beschreven in 3.2, hebben we gebruik gemaakt van de Tk listbox. Het is geen sinecure om deze keuzelijst te laten werken zoals we tegenwoordig gewoon zijn: met Tcl/Tk moeten we werkelijk alle opties en acties handmatig instellen en dit leidt tot grote stukken herhaalde code. Toen we alle drie de keuzelijsten geïmplementeerd hadden, viel ons op dat er grote gelijkenis was tussen de onderlinge werking. Om code te besparen, hebben we dan ook een methode uitgewerkt 8
Anders zou de gebruiker willekeurige variabele kunnen overschrijven door deze op te geven in zijn conguratie
le
19
Karel Nijs
Automatisatie van ASIC vericatie
Figuur 3.4:
Selectie van de technologie
die eenzelfde listbox telkens anders gebruikt. We willen even opmerken dat je onderstaande methode niet mag vergelijken met het codehergebruik van Java of VS.NET user controls. Die is namelijk veel meer high level, terwijl we hier met een aparte datastructuur werken en de speciale gevallen (de eerste en laatste keuzelijst) opvangen. 1 2 3 4 5 6 7 8 9
set varname { # text for the label # directory to scan for folders # pluriel for in status message # procedure to run when Add was clicked # name of the (global) variable # selection mode (single or multi) # the function to BIND at a listbox click }
10 11
set foundry {
20
Karel Nijs
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
Automatisatie van ASIC vericatie
"Foundry" \ "" \ "Foundries" \ {puts "new Foundry"} \ "::foundry" \ "single" \ "::listboxes::fill_next_listbox $::listboxes::counter" \ } # ... set checks { "Checks: *" \ "${::techn_0}/${::techn_1}/${::techn_2}" \ "Checks" \ {puts "new checks"} "extended" \ {::listboxes::add_check $::listboxes::counter} \ } Codefragment 3.2:
Datastructuur voor keuzelijstgeneratie
Van deze structuur worden er evenveel items aangemaakt als er gewenste keuzelijsten zijn. De eerste structuur, foundry, wordt gebruikt om de Foundry te selecteren. De laatste structuur, checks, wordt gebruikt om uit te voeren checks te selecteren. Zoals je kan zien aan de tweede parameter van de checks structuur, wordt het pad opgebouwd met behulp van (globaal) ingevulde variabelen. Deze variabelen worden ingesteld door keuzes te maken in de andere keuzelijsten. Alle keuzelijsten, behalve de eerste, werken met dit principe. De paden worden relatief genomen ten opzichte van de applicatieroot. Het gebruik van de globale variabelen ::techn_0 tot en met ::techn_3 ga je overal in de applicatie tegenkomen: met deze waarden worden ook later de verschillende delen geladen om check opties in te stellen, evenals de weergave van checkexecutie informatie. Wanneer je de datastructuur goed bekijkt, zal je opvallen dat er een zinloze opdracht tussen staat, namelijk puts "new ...". Deze opdracht staat hier omdat het Check Specications tabblad in de eerste versie ook de mogelijkheid had om nieuwe technologieën, opties, . . . toe te voegen. Deze optie is uiteindelijk niet eectief geïmplementeerd omdat we dit makkelijker kunnen beheren met een le manager. Andere velden die voorkomen in de datastructuur worden gebruikt om visuele instellingen te maken: labels, selectie mogelijkheden, . . .
21
Karel Nijs
Automatisatie van ASIC vericatie
3.4 Uitvoering checks 3.4.1 Command line options Vooraleer we de GUI opstarten, kunnen we nog kiezen om via de commandolijn enkele opties mee te geven. Deze opties overschrijven standaardinstellingen uit de conguratie les en worden beschreven in de beschikbare manual pages of wanneer men de GUI opstart met de standaard help optie. Hoe het eectief opstarten van de GUI in zijn werk gaat, is beschreven in 6.8.4. De manual page vind je in Appendix B.1.
3.4.2 Editeren rules le Het editeren van een rules le is een redelijke complexe situatie. Daarom hebben we ook een owchart (zie Appendix A.1) er voor gemaakt als leidraad voor zowel onszelf als toekomstige programmeurs.
Vooraf Elke rules le bevat een soort header met typische instellingen, speciek voor de uit te voeren check, technologie en EDA. Deze headers worden momenteel telkens met een Bash script weggeschreven in de rules le. Het is niet de bedoeling dat normale gebruikers de originele rules le kunnen wijzigen. Een normale gebruiker gaat dan ook geen gebruik maken van deze optie: ze is enkel aanwezig op speciek verzoek van een gebruiker. Rules les kunnen ook hergebruikt worden.
Editeren Voor we een rules le kunnen editeren, moeten we er eerst een kiezen door te browsen naar de locatie. (De gebruiker moet hier rechten voor hebben, zie Sectie 6.8.4. Wanneer we de rules le niet zouden editeren, worden er, bij uitvoering van de check, de juiste tags op de juiste positie geplaatst. Wanneer er al bestaande tags voorkomen, worden deze uitgecommentarieerd. Wanneer een gebruiker de rules le echter vooraf geëditeerd heeft (of een bestaande rules le herbruikt), zouden al zijn wijzigingen verloren gaan, net door dit uitcommentariëren. Hiervoor is er de optie Overwrite existing tags beschikbaar waarmee de gebruiker kan aangeven welke tags er uiteindelijk gebruikt worden. Standaard staat deze optie aangevinkt.
22
Karel Nijs
Automatisatie van ASIC vericatie
Wanneer de gebruiker naar een rules le browsed en daarna deze editeert, moet eerst de werkdirectory ingesteld zijn: hiernaar wordt immers de rules le gekopieerd. Om vergissingen tegen te gaan, wordt na editeren de Overwrite optie afgevinkt. Bij het uiteindelijke uitvoeren van de check wordt eerst gecontroleerd of de rules le al verplaatst is naar de werkdirectory. Vervolgens controleren we of we de bestaande tags al dan niet moeten overschrijven. Het zal de lezer duidelijk zijn dat dit allemaal misschien niet zo moeilijk te programmeren is, maar wel een complexe situatie voor het onderhoud inhoudt: men moet steeds dezelfde gedachtegang volgen want een kleine controle van de Overwrite optie toevoegen/verwijderen, heeft (relatief) grote gevolgen.
3.4.3 Wachtrij Executievertraging en -volgorde Omdat de implementatie van de wachtrij op zich een uitgebreid en ingewikkeld algoritme is, hebben we ook hiervan een owchart ter beschikking gesteld voor latere opvolging (zie Appendix A.3). Eén van de opties van IMEC was dat de checks remote uitgevoerd kunnen met een bepaalde vertraging (delay). Op deze manier kunnen we het belasten van de servers uitstellen tot op een tijdstip dat (waarschijnlijk) meer geschikt is om de zware checks uit te voeren. Deze vertraging hebben we globaal geïmplementeerd: er kan voor alle checks samen maar één vertragingstijd ingesteld worden. Zouden we niet op deze manier werken, dan belasten we de gebruiker van de GUI met onnodig veel instellingen (er zijn er nu al vijf per check).
Figuur 3.5:
Wachtrij met individuele starttijd voor de verschillende checks
Een andere optie zou per check specieke start tijden kunnen zijn (zie Figuur 3.5), maar dit levert enkel problemen op. Stel: we plannen een DRC check op server A om 17u00. Vervolgens laten we een tweede check, ERC, starten om 19u30. Er is dus een marge van 2,5u tussen de verschillende checks.
23
Karel Nijs
Automatisatie van ASIC vericatie
Wanneer de eerste (DRC) check echter 3u of langer duurt, gaan de twee checks tegelijk op de server uitgevoerd worden. De server wordt nu aanzienlijk belast (wat op zich geen probleem is aangezien de starttijden) en beide checks gaan langer duren. Deze kunnen nu echter een derde of misschien zelfs vierde check ook in problemen brengen. Dit ongewenste domino-eect kan makkelijk vermeden worden door een globale starttijd in te stellen. Met alleen een globale delay kunnen we echter nog altijd niet bepalen welke check nu eerst uitgevoerd wordt. Deze volgorde is van belang omdat er soms enkel de eerste check in rij uitgevoerd zal worden en bij mislukken er een interventie is van de eindgebruiker. We kunnen wel een sequentiële nummering voor elke server gebruiken, maar dan gaan we het gebruik en de implementatie onnodig ingewikkeld maken9 . Daarom hebben we gewerkt met een globale nummering voor alle checks te samen. Van deze nummering maken we een chronologisch lijstje per server. Wanneer er dubbele waardes voorkomen (er wordt bijvoorbeeld tweemaal de tweede positie gebruikt), gebruiken we de volgorde van voorkomen in de GUI. Alle voordelen van een globale wachttijd met nummering:
• geen extreme server belasting, • duidelijk en makkelijk instelbare interface voor de eindgebruiker, • eenvoudiger te implementeren, • sequentiële uitvoering
per server.
Wachtrij nog uit te voeren checks De wachtrij zelf wordt geïmplementeerd met een lijst. Een lijst is eigenlijk een primitieve, niet veilige implementatie van een queue (als ik mij die vergelijking eigen mag maken). Het eerste element van de lijst kunnen we beschouwen als de kop van de queue. Op de in Sectie 3.4.3 beschreven manier kunnen we gedistribueerd checks uitvoeren op remote servers: we moeten immers, zolang de wachttijd niet verstreken is, met een bepaald interval wachten op uitvoering. Wanneer de delay verstreken is, nemen we de kop van de wachtrij, starten deze check en plaatsen de referentie in de wachtrij van de checks in uitvoering. De precieze werking van deze laatste wachtrij wordt beschreven in 3.4.3. Zoals je kan zien op Figuur 3.5 worden de wachtrijen van alle servers met een vast interval gecontroleerd. Dit laat toe dat er haast tegelijkertijd meerdere checks kunnen opstarten (net omdat ze op verschillende servers uitgevoerd worden). Wanneer de eindgebruiker al zijn resultaten zo vlug mogelijk wil hebben, doet hij er dus best 9
Stel je een vijftal uit te voeren checks voor, telkens afwisselend op een andere server.
24
Karel Nijs
Automatisatie van ASIC vericatie
aan verschillende servers te kiezen voor elke check (een logische redenering als je rekening houdt met processorbelasting en -vermogen).
Wachtrij checks in uitvoering
Figuur 3.6:
Rij voor checks in uitvoering
De wachtrij voor de checks in uitvoering is een wachtrij met maar één element, een gevolg van de globale vertraging en de eis dat we niet meer deze gelijktijdige checks op dezelfde server willen hebben. Voor dat een check eectief gestart wordt, worden er eerst nog enkele belangrijke functies en variabelen ingevuld. Deze functies bereiden de uitvoering van de specieke check voor (zie 4) en vullen alle eigenschappen van de check in. Alle eigenschappen van elke check worden in een globale variabele bijgehouden. Deze eigenschappen worden geleidelijk aan tijdens het voorbereiden van de check ingevuld: zo worden bijvoorbeeld de rules le en server al ingesteld op de Check Specications tab. Overkoepelende instellingen zoals de GDS-le en topcell worden niet per check bijgehouden: dit zou immers verspilling van het geheugen zijn aangezien deze als standaard worden opgeslagen in de eigenschappen van de specieke Tk widgets. Voor alle duidelijkheid hebben we in Tabel 3.1 een overzicht gegeven van het geheugengebruik op het moment van executie. De verschillende statussen waar een (opdracht voor een) check zich in kan bevinden worden ook in een globale variabele bijgehouden, zie Tabel 3.2. Per uit te voeren check is er dus een ::checks_to_perform($check,...) array die telkens verder ingevuld wordt. Vooral hier merk je het gebrek aan een objectmodel. Ik heb er ook al veel tijd in gestoken en aan verloren omdat je ergens moet bijhouden welke waarden er precies onder welke indexen in de array steken10 . 10
Tcl kent geen meerdimensionale array's.
Deze worden geïmplementeerd met behulp van syntaxgevoelige
associatieve arrays (zie (4, 4.5 Multidimensional arrays)
25
Karel Nijs
Automatisatie van ASIC vericatie
Variable
Description
Example
::techn_0 ::techn_1 ::techn_2 ::techn_3
Foundry Technology Options Checks
amis 0.8um C05M-D_3M_1P {DRC, ERC, ANT}
::txtGdsFile ::txtTopcell ::txtWorkingDir
GDS-le Topcell Working directory
/path/to/gds/le GVdP_ADC018_June05 /path/to/working/dir
::checks_to_perform($check,eda) ::checks_to_perform($check,origrules) ::checks_to_perform($check,rules) ::checks_to_perform($check,copy) ::checks_to_perform($check,server) ::checks_to_perform($check,order) ::checks_to_perform($check,overwrite) ::checks_to_perform($check,starttime) ::checks_to_perform($check,pid) ::checks_to_perform($check,log) ::checks_to_perform($check,rpt) ::checks_to_perform($check,done)
EDA original rules le adjusted rules le local copy server order overwrite existing tags check starttime remote PID log le report le status of check
calibre /path/to/rules /path/to/rules 1 tarzan 2 1 56546587911
Tabel 3.1:
Value -1 0 1 2
Description Waiting Executing Finished or Failed Cancelled
Globale Tcl variabelen
Color in GUI
or
Tabel 3.2:
Check statussen in de wachtrij
26
/path/to/log/le /path/to/report/le 1
Karel Nijs
Automatisatie van ASIC vericatie
Tijdens de uitvoering van een checks kan er aan de client zijde enkel gewacht worden op voltooiing. Dit wachten is geïmplementeerd met een visuele aanduiding (een geel gekleurd Executing label) en een zichtbare klok. Hoewel het voor de eindgebruiker lijkt alsof de GUI al zijn werk al geleverd heeft, is deze continu bezig met een algoritme dat periodieke controles doet om te weten wanneer er een check voltooid zou kunnen zijn op een in gebruik zijnde server. Dit algoritme hadden we in een eerste (en haast denitieve) versie geïmplementeerd met een while lus en het Tcl after commando. Het gebruik van after leidde echter tot vele problemen: omdat Tcl niet met threads werkt, bleeft de GUI eectief gedurende het gehele interval hangen. Er werd niet meer gereageerd, op geen enkele actie. Als tijdelijke oplossing hadden we een wait_in_pieces() functie aangemaakt die, zoals de naam verraadt, het interval in stukjes verdeeld en telkens een interface update uitvoert alsvorens gedurende een volgend stukje interval te wachten. Het resultaat van deze patch was op het eerste zicht succesvol, doch bleek ze bij een reële situatie niet bevredigend te zijn. Na het raadplegen van het Internet zijn we meerdere voorkomens van dit probleem tegengekomen en ineens ook een oplossing: de immer zo eenvoudige every() functie. Deze functie voert zichzelf recursief als toplevel script uit volgens een bepaald interval. Op deze manier kunnen we wachten op voltooiing van de checks, maar nog steeds de faciliteiten van de GUI gebruiken: monitoring van de check, opvolging applicatielog, herbekijken van de instellingen, . . . De implementatie van het eectief contacteren van de server wordt verzorgd door een zelf geschreven Tcl C extensie die, beveiligd met SSL, volgens het ASICproto met de remote server communiceert. Een uitgebreide uiteenzetting vind je in 6.8.
3.4.4 Check monitoring Een belangrijk onderdeel van de GUI is de mogelijkheid om de checks in uitvoering op te volgen. De GUI wordt ook hier weer enkel gebruikt om een high level resultaat (en besturing) weer te geven, terwijl alles door de onderliggende netwerklaag uitgevoerd wordt. Voor dat er een check op een remote server opgestart wordt, worden er aan de clientzijde paden naar log en errorlog les gekozen. Deze les worden dan gebruikt om de uitvoer van het standaard uitvoer- en foutkanaal op te vangen. (Voor een gedetailleerde bespreking verwijzen we naar 4.1.1.) De Check Monitoring toplevel widget (Figuur 3.7) bundelt alle checkinformatie voor de eindgebruiker en voorziet enkele live monitoring vensters. Er is de mogelijkheid om zowel de log als de errorlog le te bekijken. Wanneer de check voltooid is, kan je het rapport bekijken.
27
Karel Nijs
Automatisatie van ASIC vericatie
Figuur 3.7:
Check Monitoring toplevel widget
Meestal gaan de log en errorlog le niet tegelijk ingevuld worden: er zijn namelijk zoveel verschillende errors die kunnen voorkomen dat ofwel de één, ofwel de ander ingevuld wordt. Wanneer de EDA-software met een fout eindigt11 , gaat deze dit echter niet via het standaard error kanaal melden (zoals we gewoon zijn), maar als onderdeel van de standaard uitvoer! De scheiding van de log en errorlog les komt vooral tot zijn recht wanneer er shell en/of systeemfouten optreden. Wanneer de Calibre EDA bijvoorbeeld tijdens de uitvoering van een check een systeemfout krijg (bv. geheugenfout), gaat dit wél naar het standaard foutkanaal gestuurd worden. De eindgebruiker kan in dit geval (een deel van) de Calibre uitvoer zien in de eerste tab, terwijl de (fatale) foutmelding in de tweede tab gevonden kan worden. Het gebruik van deze live logging is volledig gesteund op het, door ons ontworpen, ASICproto protocol en de netwerkstructuur van IMEC met gemeenschappelijke root. 11
Wanneer er bijvoorbeeld een in te voegen bestand niet gevonden wordt
28
Karel Nijs
Automatisatie van ASIC vericatie
3.4.5 Annuleren van checks Tijdens het ontwikkelen en testen van de applicatie12 deed er zich een interessante situatie voor: wanneer er een probleem voorkwam, was de bediener van de GUI verplicht om te wachten totdat de checks in uitvoering voltooid waren opdat de executie eectief stopte na drukken op de Stop knop. Dit is een onaangename situatie die tot grote ergernis van de eindgebruiker kan leiden en dus zeker moet opgelost worden. Hiervoor is de mogelijkheid geïmplementeerd om checks in uitvoering te annuleren, ook weer steunende op het ASICproto protocol. Dit annuleren wordt op verschillende manieren gebruikt:
• je kan checks die nog niet in uitvoering zijn (maar dus wel aanwezig in de wachtrij) annuleren. • bij het drukken op de Stop knop wordt eerst de algemene uitvoering stop gezet, vervolgens worden alle checks in uitvoering geannuleerd. Checks die niet in uitvoering zijn, blijven in hun huidige status (waiting, finished of failed). • bij het afsluiten van de applicatie worden, na bevestiging door de gebruiker, alle checks in uitvoering geannuleerd. Wanneer een check succesvol voltooid is, wordt de Cancel-knop vervangen door een Report-knop. Met deze laatste kunnen de gebruikers rechtstreeks het rapport openen, zonder van de Monitoring faciliteit gebruik te maken.
3.5 Foutafhandeling Tcl heeft een ander foutafhandelingsmodel dan dit van Java en C++ waaraan we ondertussen al gewoon zijn13 . We kunnen hier weliswaar ook excepties opvangen en werpen, maar de methode is moeilijker en de mogelijkheden beperkt. Daarom hebben we vooral gewerkt met traditionele foutafhandeling met behulp van de programmeertaal14 . Wanneer een functie vroegtijdig beëindigd wordt (moet worden), gaan we de fout melden (zie verder) en een bepaalde terugkeerwaarde instellen. De oproeper beslist dan wat er met het resultaat van de opgeroepen functie zal gebeuren. Later, in de bespreking van de netwerklaag, komen we nog eens terug op foutafhandelingen, maar dan met de mogelijkheden die C++ ons te bieden heeft (zie 6.3.1). Het melden van een fout gebeurt op twee manieren: 12 13 14
De applicatie is grotendeels thuis geschreven met zelf geschreven zware EDA emulatie scripts Eigenlijk zijn er zelfs nog essentiële verschillen tussen het Java en C++ model Zie cursus Beveiliging, hoofdstuk 14 Exception handling
29
Karel Nijs
Automatisatie van ASIC vericatie
1. er wordt een bericht getoond in de statusbalk, 2. de foutbeschrijving wordt doorgegeven aan de Debug
klasse 15 .
Het loggen gebeurt in drie levels, zie Tabel 3.3. Op deze manier kan de Debug module altijd gebruikt worden om zowel applicatie-informatie als opgetreden fouten weer te geven. De eerste twee levels genereren enkel berichten in statusbalk, applicatielog en/of console. Het laatste level genereert een toplevel foutbericht met het Tcl error commando. Voor dat de gebruiker de applicatie opstart, kan hij zelf via de commandolijn (optie -silent 0/1) kiezen met welk debuglevel hij wil werken. Standaard worden enkel foutberichten getoond. Kleine fouten, zoals bijvoorbeeld een onbereikbare server, worden in silent mode als een éénregelig bericht gemeld in de console, terwijl je in luide modus een volledige beschrijving krijgt. In de applicatielog worden altijd de volledige foutbeschrijvingen gelogd. Er is hier geen beveiligingsrisico mogelijk. Het debuglevel van de onderliggende Tcl C extensie, de socket voor ons protocol (zie verder), kan ook expliciet ingesteld worden, maar enkel door administrators. Deze instelling is dan ook niet beschikbaar via de commandolijn. Wanneer je deze debugoptie gebruikt, komt er wél gevoelige informatie terecht in de consoleuitvoer en applicatielog van de GUI16 . De beheerders is dan ook aangeraden deze instelling niet te wijzigen, doch blijft ze aanwezig. Opnieuw om latere opvolging te vergemakkelijken.
3.6 Codedocumentatie Om de code te documenteren, hebben we gebruik gemaakt van een JavaDoc-achtige tool, AutoDoc17 . 15 16 17
In Tcl is dit eigenlijk een gewone Tcl module, bestaande uit verschillende procedures Zoals bv. de inhoud van de verstuurde en ontvangen berichten http://www.oche.de/ akupries/soft/autodoc/
Loglevel 0 1 2
Beschrijving Enkel gebruikt voor logmessages. bv. checks die net voltooid zijn en dit melden. Foutmeldingen waarna de applicatie nog normaal kan verder werken. bv. een server die niet bereikt kan worden Fatale fouten die de werking van de applicatie in gevaar brengen. bv. wanneer een standaard commando zoals gscan niet gevonden wordt Tabel 3.3:
Verschillende loglevels
30
Karel Nijs
Automatisatie van ASIC vericatie
AutoDoc wordt verdeeld met de GPL licentie en er is dus geen probleem om deze tool te gebruiken voor dit project. De AutoDoc tool kan overweg met de JavaDoc tags, ondanks enkele subtiele verschillen die we hier niet ga uitleggen. Een groter probleem waren echter de gebreken van AutoDoc die tevoorschijn kwamen bij het gebruik van uitgebreid commentaaar en/of commentaar verspreid over meerdere regels. Dit alles resulteerde in een API die haast volledig onleesbaar was. Om deze gebreken op te vangen, hebben we de bestaande broncode van AutoDoc lichtjes gewijzigd. Deze gewijzigde code is toegevoegd aan alle bestanden van dit project, zodat IMEC later zelf ook een nieuwe (leesbare) API kan genereren.
31
Hoofdstuk 4
EDA speciek Gedurende de uiteenzetting is er regelmatig verwezen naar instellingen, scripts, . . . die speciek voor elke EDA gemaakt moeten (in principe checkonafhankelijk). Ik zal deze hier kort proberen te verduidelijken. Om de werking van beide EDA's uit te zoeken, heb ik verscheidene bronnen kunnen raadplegen:
• mijn interne promotor, Erwin; • de verschillende bestaande scripts om een check uit te voeren; • de grote en goed gedocumenteerde handleidingen van Calibre en Dracula.
4.1 Calibre 4.1.1 Rules le De Calibre EDA is de eerste die we eectief volledig geïmplementeerd en getest hebben. De rules les voor de Calibre EDA zijn tekstbestanden (grootte-orde <1 MB) met hierin verwijzingen naar:
• specieke tags waarnaar de software bij uitvoering zoekt; • andere include les die tussengevoegd moeten worden op de positie waar de opdracht voorkomt. In de 3.4.2 sectie hebben we al een tipje van de sluier opgelicht omtrentd het editeren van de rules le. Nu we eectief de check willen uitvoeren, moeten we de rules le eerst parsen. Aan de hand van in de GUI gekozen instellingen worden bepaalde tags weggeschreven. Alle bestaande tags die we tijdens parsen tegen komen, blijven in de rules les, maar worden in commentaar gezet.
32
Karel Nijs
Automatisatie van ASIC vericatie
Vervolgens gaan we elke include lijn verwerken: deze lijn verwijst absoluut relatief naar een bestand dat op een server bij IMEC staat. Mijn begeleiders vonden het een goed idee om het bestand uit de verwijzing in te lezen en volledig tussen te voegen. Op deze manier krijgen we een complete rules le: handig bij opvolging en verdere pogingen. Wanneer een in te voegen rules le niet gevonden wordt, hebben we er voor gekozen om de verwijzing ongewijzigd in de rules le te laten staan. Deze benadering gaat van de veronderstelling uit dat de opgegeven rules le correct was en er wordt geen foutmelding gegeven. Wanneer we hier wél een foutmelding zouden geven, zouden we een mogelijk complexe situatie creëren voor eindgebruikers die geen notie hebben van het hele rules le gebeuren. De foutmelding zal immers toch gegenereerd worden, maar dan wel door de Calibre EDA en in een, voor de eindgebruiker, vertrouwd en begrijpbaar formaat. Tijdens de het voorbereiden van de rules le moeten er ook enkele bestanden aangeduid worden waarin informatie opgeslagen wordt:
• rules le: De rules le heeft eigenlijk twee functies: controle en referentie. Gevonden fouten kunnen hierin opgezocht worden met behulp van de referentie uit het Summary Report. • Calibre Summary Report: deze le wordt door de Calibre EDA gebruikt om fouten in de opbouw van de ASIC weer te geven. Deze fouten worden volgens een vast en vooraf bekend formaat weergeven. Ook zijn er verschillende waarschuwingen die kunnen optreden. Elke fout wordt hier vermeld met een speciale referentie die we terug kunnen vinden in de rules le. • Calibre Results Database: hierin komt meer cryptische informatie over de gevonden fouten terecht. Deze database wordt momenteel niet gebruikt. • log le: gebruikt om de standaard uitvoer van Calibre op te vangen om het gevoel van monitoring te kunnen geven aan de eindgebruiker.
live
• errorlog le: zelfde functie als de logle, maar nu voor het standaard foutkanaal.
4.1.2 Executie De Calibre software kan zowel op het GNU/Linux als HP-UX platform uitgevoerd worden. Voordat we de Calibre software kunnen aansturen, moeten de paden naar de installatie- en licentie directory's gezet worden. Deze instellingen worden gemaakt door een source script uit te voeren in de huidige shell. Bij IMEC werken ze normaal enkel met TC-shell, een uitgebreidere variant van de oeroude Cshell. Omdat we echter graag de uitvoer van het standaard uitvoer- en foutkanaal gescheiden
33
Karel Nijs
Automatisatie van ASIC vericatie
willen hebben, voor betere opvolging, zijn we verplicht een shell te gebruiken met meer mogelijkheden. Omdat de Bourne Again Shell (Bash) standaard geïnstalleerd is op zowel clients als servers en we op de hoogte zijn van de (vele) mogelijkheden van deze shell, hebben we besloten de bestaande source scripts te herschrijven in Bash. Omdat deze scripts zeer kort en de conversie trivaal is, gaan we hier niet verder over uitweiden. Wanneer de gebruiker de check op de server afvuurt en wanneer dit mislukt, is het belangrijk om te weten waar er precies een fout voorgekomen is. Als oplossing kan je hiervoor de mogelijkheden van de Bash shell gebruiken en de voorwaardelijke uitvoering van de EDA koppelen aan het al dan niet slagen van de uitvoering van het source script. Ook de standaard uitvoer- en foutkanalen worden gebundeld. Een resultaat van deze combinatie kan je terugvinden in Codefragment 9.
4.1.3 Rapportgeneratie Wanneer een check (succesvol) voltooid is, kunnen de gebruikers het resultaat van standaard uitvoer en/of de Calibre Summary File en Results Database raadplegen. Omdat deze manier echter nogal omslachtig is en de gewone gebruiker meestal enkel wil weten of de GDS-le nu wel degelijk voldoet, is het handig wanneer er door de GUI zelf automatisch een samenvatting gegenereerd wordt. Deze samenvatting, het rapport, kan opgesteld worden met de informatie die we terugvinden in de rules le en de Calibre Summary File. De Calibre Summary File bevat allerlei informatie: globale informatie over de check, waarschuwingen, aantal overtredingen (fouten) per referentie en ten slotte ook nog een samenvattend rapport. Al deze secties zijn (gelukkig) duidelijk afgebakend en mits je enkel speciale handles kent, kan je aan de hand van deze twee les een duidelijk en overzichtelijk rapport genereren. Het genereren van het rapport gebruikt functies die door gespecialiseerde tekstverwerkingssoftware zoals awk beter en eciënter geïmplementeerd zijn. IMEC vindt het echter belangrijk dat het aantal gebruikte programmeer- en scripttalen tot een minimum beperkt wordt: er zijn verscheidene mensen op IMEC aanwezig die notie hebben van Tcl, maar niet zo zeer van andere talen. Ook hebben we ook minder afhankelijkheden wanneer we hiervoor enkel Tcl zouden gebruiken. In ieder geval moet ook ons Tcl script, net zoals de awk tool, elke regel in de bronle(s) verwerken. We zullen dan ook proberen dit zo eciënt mogelijk te doen. Het eerste en laatste deel van de Calibre Summary File kunnen we als het ware als header en footer beschouwen voor ons rapport. Er is geen nood om informatie over de voltooide check vanuit de GUI te verzamelen en weg te schrijven wanneer deze al aanwezig is in een ander bestand! Het uiteindelijke rapport zal naar de klant gestuurd worden. Om deze niet te overweldigen, gaan
34
Karel Nijs
we de headers iets
Automatisatie van ASIC vericatie
lichter maken.
Om het aantal waarschuwingen te tellen en het opzoeken van foutbeschrijvingen in de rules le te verwezelijken, hebben we gewerkt met handles. Deze handles kunnen in de namespace van de Calibre module gedenieerd worden. Het vinden van de handles is (natuurlijk) gebaseerd op reguliere expressies. Voor het opzoeken van de foutreferentie in de rules le wordt de grep tool gebruikt. Weliswaar een extra afhankelijkheid, maar wel één die zo elementair is, dat het geen probleem zal opleveren. grep laat toe om makkelijk naar bepaalde woorden en/of zinnen te zoeken, terwijl awk meer scriptgebaseerd is. Omdat we het kunnen redden met de combinatie Tcl-grep, hebben we geen andere extra software meer nodig. Een voorbeeld van het uiteindelijke rapport kan je terugvinden in Appendix D.1.
4.1.4 Clean up Calibre is propere software: er worden geen bestanden gegeneerd die we later niet meer nodig hebben en de directory vervuilen.
4.2 Dracula Het opzetten en aansturen van een Dracula check komt grotendeels overeen met de werkwijze van de net beschreven Calibre EDA. Er zijn echter enkele subtiele verschillen.
4.2.1 Rules le Een rules le voor Dracula wordt anders opgebouwd: hier is er geen Results Database. Er zijn wel gelijkaardige bestanden:
• INDISK is de rules le; • OUTDISK bevat de cellen waarin fouten zijn opgetreden; • PRINTFILE is de prex die gebruikt wordt bij alle output les die Dracula genereert (zie ook 4.2.2). Deze tags bevinden zich in een Description blok in de rules le. Zoals bij Calibre worden albestaande tags in commentaar gezet (tenminste als deze optie ook gewenst is). In tegenstelling tot een Calibre rules le moet een Dracula rules le niet doorzocht worden op mogelijke includes om deze tussen te voegen. De Dracula rules le moet echter wél vooraf gecompileerd worden: een Dracula check vereist immers een voorgecompileerde rules le. Op deze manier krijgen we nog een extra foutmogelijkheid erbij omdat deze compilatie immers ook kan mislukken.
35
Karel Nijs
Automatisatie van ASIC vericatie
4.2.2 Executie Om de rules le te compileren, maken we gebruik van het PDRACULA commando. Dit proces kan geautomatiseerd worden door te werken met een input le. Deze kunnen we op voorhand aanmaken en de padverwijzing naar de centrale directory gebruiken. De input le zelf is kort en ziet er zo uit: 1 2
/G /path/to/dracula/rules N /F Codefragment 4.1:
PDRACULA input le
Ook hier moet de uitvoerende shell weer gecongureerd worden. Enkel de PATH Shell variabele aanvullen volstaat echter in dit geval. De Dracula software kan enkel op het HP-UX platform uitgevoerd worden. Het uiteindelijke commando wordt wat langer en ingewikkelder dan dit van Calibre: 1 2
# zonder de variabelen ingevuld set cmd "bash -c '( $src && PDRACULA < $ifile && ./jxrun.com) >$log 2>$errlog "
3 4 5
6
7
# met de variabelen ingevuld set src "PATH=\${PATH}:/imec/other/invosoft/Software/dracula/COM:/imec/other/ invosoft/Software/dracula/SCRIPTS/)" set src "$src ; PATH=\${PATH}:/imec/software/cadence/release2003/ic_v5.0.32/tools /dracula/bin/64bit" set cmd "bash -c '( $src && PDRACULA < /path/to/input/file && ./jxrun.com) >/path /to/log 2>/path/to/errlog ' "
Volledig Dracula commando
Codefragment 4.2:
Dracula genereert (bij uitvoeren van de executable jxrun.com) onder andere volgende output les (zie Tabel 4.1). Type of run
DRC
ERC
PRINTFILE = INPUT LOG ERROR ERC SUMMARY SUMMARY FILE DISCREPANCY
DRCPRT DRCPRT.INP DRCPRT.LOG DRCPRT.ERR (NONE) DRCPRT.SUM (NONE)
ERCPRT ERCPRT.INP ERCPRT.LOG ERCPRT.ERR ERCPRT.ERC ERCPRT.SUM (NONE)
Tabel 4.1:
Dracula output les
36
Karel Nijs
Automatisatie van ASIC vericatie
4.2.3 Rapportgeneratie De Dracula rapportgeneratie is checkafhankelijk en ingewikkelder dan deze van Calibre, mede door al de extra bestanden die genereerd worden. Ook de informatie die we terug krijgen is moeilijker te bevatten omdat deze nu verspreid is over al die les. Om de rapporten hetzelfde uitzicht te geven, wordt er eerst door ons een rapport header naar het rapportbestand geschreven. Deze is samengesteld uit de informatie die we op kunnen vragen uit de GUI1 . De rapport footer is ook niet aanwezig en kunnen we niet zelf samenstellen: deze bevat immers informatie over de precieze duur, geheugen- en processorgebruik van de uitgevoerde check. Je zou deze informatie eventueel kunnen vergaren door gebruik te maken van Bash functies en procesopvolging, maar hiervoor hebben we geen tijd meer gehad. Het uit te voeren commando zou immers ook te lang worden om in één keer te kunnen versturen met ons ASICproto protocol (wat eventueel ook weer op te lossen is. . . ). Het samenstellen van de rapport inhoud verloopt in vier delen: 1. Wanneer we een niet-DRC check uitgevoerd hebben, wordt de LOG le, dracjob.log doorzocht. Dit bestand moeten we regel per regel overlopen en aan de hand van reguliere expressies zoeken naar DIFFERENT LABELS en OPENED/SHORTENED NOTES vermeldingen. Hierna verwerken we ook de ERC SUMMARY le, dracjob.erc, en zoeken we naar OPEN/SHORT DISCARDED vermeldingen2 . 2. Voor alle type checks controleren we de SUMMARY FILE, dracjob.sum, op illegale data met behulp van een aantal vooraf gedenieerde handles. 3. Met behulp van het explain script geven een lijst met overtredingen weer. 4. De laatste stap maakt een overzicht van alle error cells en hun beschrijving. De informatie voor de laatste twee stappen wordt uit de SUMMARY FILE gehaald. Omdat we hier met verschillende geopende les zitten, wordt alle uitvoer eerst weggeschreven naar (enkele) tijdelijke les. Om tijdelijke les te genereren is er in de common_procs.tcl module een specieke functie die de naam baseert op het aantal clock clicks.
4.2.4 Clean up In de Calibre Clean up sectie hebben we vermeld dat Calibre een propere tool is. Dracula laat echter veel bestanden achter in de directory waar de check uitgevoerd wordt. 1 2
Bij Dracula vinden we deze informate
niet
terug in het resultaat
In de praktijk doen deze fouten zich eigenlijk niet voor. We hebben dit gedeelte dan ook niet kunnen testen
37
Karel Nijs
Automatisatie van ASIC vericatie
Deze vervuiling is zelfs zo erg, dat er meer dan 20 bestanden achter blijven met de KEEPDATA optie op NO gezet. Daarom wordt er na de Dracula rapport generatie de werkdirectory van de voltooide check uitgekuist. Het opruimen van deze les is sterk afhankelijk van de gebruikte Dracula naamgeving(en) en kan niet volledig opgelost worden met reguliere expressies.
38
Deel III
Netwerklaag
39
Hoofdstuk 5
Netwerklaag: algemeen en beveiliging 5.1 Inleiding Omdat we commando's gedistribueerd op remote servers willen uitvoeren, moeten we op één of andere manier deze commando's kunnen doorsturen over het netwerk. De commando's worden in de GUI opgebouwd met behulp van parameters, door de gebruiker zelf in te stellen, en vervolgens uitgevoerd door de geschikte server, ook gekozen door de gebruiker van de GUI. Het is hier belangrijk dat de clients ten opzicht van de servers geauthenticeerd worden: anders zou iedereen commando's kunnen uitvoeren op de server of zijn er DoS aanvallen mogelijk. Omdat we de applicatie vanaf de lokale host kunnen opstarten en de checks op de servers uitgevoerd worden, moet ze via het netwerk contact maken met de verschillende servers tegelijk. Vervolgens worden de checks op de server uitgevoerd (in de GUI moet er de mogelijkheid zijn dit proces visueel te volgen). Na voltooien van de check wordt er in de GUI aan de gebruiker duidelijk gemaakt dat de check voltooid is (zie 3.4.3). De applicatie wordt pas afgesloten wanneer alle checks voltooid zijn. Verder zullen we ook nog het CPU gebruik en het aantal ingelogde gebruikers van de servers moeten opvragen, maar dit is eigenlijk een vereenvoudigde versie van het remote execution probleem en gaan we niet apart behandelen.
5.1.1 Situtatieschets Uitleg bij het uitvoermodel (Figuur 5.1): 1. Vanuit de Tcl GUI worden de commando's voor een check uit te voeren, opgebouwd. 2. Wanneer een bepaalde delay verstreken is, geeft de GUI het commando door aan de netwerklaag.
40
Karel Nijs
Automatisatie van ASIC vericatie
Figuur 5.1:
Vereenvoudigd proces van remote execution
3. Deze (de eigenlijke client ) neemt volgens het ASICproto protocol contact op met de server. 4. De server luistert naar inkomende requests van clients. Wanneer de server een request krijgt, moet de client gecontroleerd worden en start de communicatie. 5. De client stuurt
alle commando's door naar de server, die ze dan ineens uitvoert.
6. Bij het uitvoeren wordt de output van de commando's geredirect naar een bestand in een opgegeven werkdirectory en de server sluit de verbinding. 7. De client kan, om het proces op te volgen, van het bestand lezen (er is geen verbinding meer tussen client en server). Dit bestand blijft voortbestaan na het voltooien van de check en kan later eventueel geraadpleegd worden ter controle. Het hoofdprobleem van dit alles is natuurlijk eenvoudig in te zien: als er service op de server aanwezig is die willekeurig commando aanneemt, dan kan hier makkelijk misbruik van gemaakt worden. Stel dat de service op de server opgestart is onder gebruiker asicgui, behorende tot de groep asicgui. Wanneer deze gebruiker rechten heeft van een bepaalde directory die alle GDS-les bevat, dan kan deze bijvoorbeeld een commando doorsturen die deze directory gewoon volledig wist. Wat een catastrofe zou zijn voor het verdere verloop van de activiteiten van EUROPRACTICE.
41
Karel Nijs
Automatisatie van ASIC vericatie
Voor dit uitvoermodel zijn er meerdere oplossingen mogelijk:
• uitvoeren via SSH; • uitvoeren via een server service, geïmplementeerd als Tcl extensie; • uitvoeren via een C module met rexec(). Deze kunnen dan nog eens opgedeeld worden in:
• de commando's apart doorsturen, • een Bash script maken en dit uitvoeren, • een Tcl script maken en dit uitvoeren.
5.2 Remote execution met SSH Voor de scripts op de server uit te voeren kan men in Tcl makkelijk gebruik maken van SSH: deze functie kan via een bepaald Tcl commando uitgevoerd worden en (waardes van) Tcl variabelen kunnen zo meegegeven worden1 : 1
set res [exec $::env(SHELL) -c "ssh \$path \$source \$command"]}
Het meegegeven commando wordt door Tcl in een virtuele shell uitgevoerd en het resultaat ervan opgeslagen in de variabele res. Het programma stopt met uitvoeren wanneer het commando voltooid is en de res variabele gezet is. Enkele problemen hierbij:
• Voor het kunnen uitvoeren van zo'n commando moeten telkens het PATH en de source gezet worden zodat de juiste scripts uitgevoerd worden. Het uitvoeren van een check vereist meerdere commando's (zie Codefragment 8 en 9) en het PATH en source moeten dus telkens opnieuw ingesteld worden. • Tcl heeft geen threads zodat we niet meerdere commando's tegelijk kunnen uitvoeren. Dit is een probleem, want we moeten namelijk SSH'en naar verschillende servers tegelijk voor écht distributief de checks uit te kunnen voeren. Dit probleem is eventueel op te lossen door een ingewikkelde datastructur aan een klokfunctie te hangen en uitvoerende functies te markeren. • Als we SSH gebruiken, moeten we remote inloggen op de server. Hiervoor zijn login en paswoord vereist en omdat we hier een virtuele shell hebben, zullen we deze prompt nooit te zien krijgen. De gebruikers van het programma wíllen ook niet nog eens het paswoord invoeren: dit doen ze al wanneer ze inloggen op hun PC2 . 1 2
Tcl vereist dat hier backslashes staan voor het dollarteken Op *nix is het niet mogelijk om je paswoord als leesbare tekst op te vragen
42
Karel Nijs
Automatisatie van ASIC vericatie
5.2.1 Oplossingen voor interactief inloggen met SSH expect installeren expect is een script dat je bepaalde antwoorden aan een interactieve applicatie kan laten geven op basis van regulurie expressies. Enkele nadelen van expect:
• Het is een apart programma en moet dus ook centraal geïnstalleerd worden (belangrijkste reden). • expect is zeer syntax gevoelig en de applicatie kan, bij wijzigen van de output van een afhankelijke applicatie, niet meer correct functioneren. • Het programmeren en opvangen van expect in Tcl lijkt me wanordelijk.
Een sleutelpaar genereren Met een sleutelpaar kunnen we het inloggen automatiseren: er moet een SSH sleutelpaar aangemaakt worden en de client sleutel moet in de guiasic project account geplaatst worden. Wanneer we deze sleutel geautomatiseerd willen gebruiken (ie. zonder invoer van paswoord), moeten we een sleutel zonder paswoord maken en deze sleutel toevoegen aan het /.ssh/authorized_hosts2 bestand van de server.
5.2.2 Problemen bij SSH executie Situatieschets Wanneer we een check vanop afstand uitvoeren met bijvoorbeeld SSH kunnen we dit proces lanceren op verschillende manieren:
• we starten SSH én de check op de
voorgrond op,
• we starten SSH op de achtergrond (optie -f) en de check op de voorgrond op, • we starten SSH op de achtergrond (optie -f) en de check op de achterground (optie &) op. Bij het opstarten van een SSH proces kunnen we via Tcl commando's de process id van dit proces en de le descriptor krijgen. We kunnen dus het SSH proces afsluiten en/of de communicatie ermee. Op deze manier moeten we zelfs slechts één variabele per check bijhouden. Een vereenvoudigd voorbeeld van het opstarten van het proces: 1 2
set cmd "ssh -nq ${::proguser}@$host \"calibre >log 2>&1 \"" set pipe [open "| $cmd" "r"] Codefragment 5.1:
Vereenvoudigd voorbeeld van opstarten remote proces
43
Karel Nijs
Automatisatie van ASIC vericatie
Onderbreken van processen Wanneer we het SSH commando beëindigen, blijft het meegegeven proces (in bovenstaand voorbeeld Calibre) uitvoeren totdat het voltooid is. Dit kan een probleem vormen als je weet dat de checks tot twee dagen kunnen duren. Op deze manier zijn we in de Tcl GUI onze handle kwijt en kunnen we onmogelijk het verdere verloop van het proces opvolgen: alle processortijd is dus verloren. Als oplossing kunnen we de PID opvragen van het uitgevoerde commando en vervolgens, ook weer met SSH, de server contacteren om te controleren of de PID bestaat. Als de PID bestaat3 , sluiten we het af. Een voorbeeld: 1 2 3
$ kill -0 4148 $ kill -0 999999 bash: kill: 999999: no such pid
Toegepast op onze Tcl GUI: 1
set cmd "kill -0 $p_id"
2 3 4 5 6 7 8 9 10 11 12 13 14
if [catch {set res [::network::run_cmd $::proguser $host $cmd]} err_msg] { if {[regexp -nocase {(.*)kill(.*)} $err_msg] == 1} { # SSH connection OK, #"bash: kill: (xxxx) - No such process" returned # process does NOT exist (or is already finished) } else { # SSH error occurred } } else { # no message ---> means: STILL RUNNING # kill process } Codefragment 5.2:
Controleren via SSH of remote PID bestaat
De process ID De PID is een unieke Je kan de PID
identier voor een (actief) proces op een *nix computer.
rechtstreeks te weten komen door:
• een ampersand & mee te geven wanneer je het proces uitvoert (het proces wordt dan ook op de achtergrond uitgevoerd); • onmiddellijk na het proces $! uit te voeren. Met $! komen we de PID van het laatste & uitgevoerd commando te weten. 3
Dit kunnen we controleren met het commando
kill
44
met
Karel Nijs
Automatisatie van ASIC vericatie
Wanneer je echter via SSH werkt, werkt de & operator niet meer en kom je de (remote) PID niet te weten. We moeten dus een andere manier zoeken om het proces in uitvoering te stoppen.
SSH proces beëindigen We kunnen het uitgevoerde commando samen met het SSH commando laten beëindigen door de optie -t mee te geven aan de SSH opdracht: 1
$ ssh -tnq user@host "calibre >log 2>&1"
Op deze manier kunnen we echter niet het SSH commando gebruiken in onze GUI: de -t optie vereist immers dat stdin en stdout verbonden zijn vooraleer er een pseudo-terminal aangemaakt wordt. Een mogelijke oplossing voor dit probleem: wanneer we een wrapper rond het SSH commando maken, kunnen we hem wijsmaken dat de stdin en stdout wél verbonden zijn. Op deze manier kunnen we dus wel gebruik maken van de -t optie. Om deze optie te kunnen verwezelijken, moeten we eerst de Perl IO::pty module downloaden van http://www.cpan.org en installeren. Vervolgens kunnen we SSH uitvoeren met de Perl wrapper: 1
$ pty.pl ssh -tnq karel@localhost "calibre >log 2>&1" Codefragment 5.3:
SSH uitvoering met Perl wrapper
We kijken of het Calibre proces bestaat: 1 2
3 4 5
$ ps a | grep calibre | grep -v 'grep' 10363 pts/2 S+ 0:00 /usr/bin/perl -w pty.pl ssh -tnq karel@localhost calibre >log 2>&1 10364 pts/2 S+ 0:00 ssh -tnq karel@localhost calibre >log 2>&1 10368 pts/5 Ss+ 0:00 bash -c calibre >log 2>&1 10369 pts/5 S+ 0:00 /bin/bash /usr/bin/calibre
Daarna sluiten we het SSH proces met
: 1 2
# uitvoer van: pty.pl ssh -tnq karel@localhost "calibre >log 2>&1" Killed by signal 2.
De uitvoer van het Calibre script is nu ook gestopt: 1 2
$ ps a | grep calibre | grep -v 'grep' $
Deze methode werkt enkel in console zoals boven beschreven. Wanneer we de Perl module oproepen vanuit onze GUI, moeten we nóg eens de optie -t meegeven.
45
Karel Nijs
Automatisatie van ASIC vericatie
5.2.3 Signalen opvangen Wanneer je de opbouw van het uit te voeren commando voor bijvoorbeeld de Calibre EDA, begrijp je waarschijnlijk dat deze syntax en opbouw zeer foutgevoelig is. 1 2
# uit te voeren commando; alle Tcl variabelen moeten nog ingevuld worden set cmd " bash -c '( $src && calibre -drc -$::calibre::hier -turbo -nowait $::checks_to_perform($check,rules) ) >$log 2>$errlog '"
3 4 5
# het volledige commando set cmd " bash -c '( source /imec/software/mentor/EN2004/setup/ calibre_v2004.3_9_hpux.csh && calibre -drc -hier -turbo -nowait /path/to/ rules/file ) >/path/to/log/file 2>/path/to/error/log/file '"
6 7 8
# SSH wrapper om het commando te versturen set cmd "ssh -nqf -t -t karel@local$host \" { bash -c '( source /imec/software/ mentor/EN2004/setup/calibre_v2004.3_9_hpux.csh && calibre -drc-hier -turbo -nowait /path/to/rules/file ) >/path/to/log/file 2>/path/to/error/log/file '} \"" Codefragment 5.4:
Opbouw Calibre commando met SSH
Omdat we SSH met een Tcl commando oproepen en de output van dit commando redirecten naar een pipe in Tcl, kunnen er verschillende fouten optreden:
• Tcl fouten zoals bv. het mislukken van het mando, ...
pipe commando, fout gestructureerd Tcl com-
• Shell syntax fouten zoals bv. fout gestructureerd (Shell) commando, ontbreken van SSH op client PC, ... • SSH fouten zoals bv. het ontbreken van een sleutel, mislukken van de connectie, ... Als deze fouten kunnen we maar op één manier opvangen in onze Tcl GUI (zie Codefragment 5.2). Ik heb dit proberen te doen met reguliere expressies en opvolgen van de pipe uitvoer, maar het was onmogelijk om hiervoor een eenduidige en altijd werkende methode te ontwerpen. Het is makkelijker wanneer we SSH zouden herschrijven en abstraheren: op deze manier kunnen we zelf bepalen welke signalen er doorgeven worden aan de GUI en met welke bijhorende berichten. Ook moeten we dan niet meer werken met een Tcl pipe om de uitvoer op te vangen van het Tcl commando dat het SSH commando uitvoert met als parameter een Bash commando (je ziet nu meteen de net beschreven moeilijkheid van foutopvanging in).
5.3 Remote executie via een C service Zoals eerder vermeld, biedt Tcl de mogelijkheid om zelf uitbreidingen te schrijven in ANSI C. Met deze uitbreidingen kan er dan gecommuniceerd worden met de rest van het Tcl programma.
46
Karel Nijs
Automatisatie van ASIC vericatie
Tijdens mijn stage is er al een deel van deze service uitgewerkt: 1. De Tcl GUI voert de module uit en geeft inline alle commando's mee die uitgevoerd moeten worden (zie Codefragment 2). 2. De extensie contacteert de server en stuurt de commando's door naar de server. 3. Na het sturen van het laatste commando sluit de een van de hosts de verbinding. Hoe de uitvoering van dit commando precies in zijn werk gaat, kan je terugvinden in 6.6.3. Mogelijke manieren om de output door te sturen van de server naar de client:
• We redirecten de output naar een bestand (dat zich bevindt in de centraal beheerde directory). Voordeel: met een Tcl equivalent voor tail -f kan zo het aanvullen van de le live worden getoond in de GUI. • We maken een FIFO aan en hiernaar redirecten we de output van de commando's. Nadeel: we zouden eventueel de uitvoer willen bijhouden voor later raadpleging.
Beveiliging Een probleem van deze methode is de beveiliging: als er op de server een service draait waar iedereen commando's kan naar sturen en deze uitgevoerd worden, is er een zeer groot beveiligingsprobleem.
5.3.1 Uitvoeren via een C module met rexec() Deze mogelijkheid, beschreven in de manual page van rexec, kan een commando of script uitvoeren op een server door de lokale gebruiker en paswoord op te vragen. Via C functies kan je makkelijk aan de échte gebruiker komen (ook na su gebruik). Vervolgens wordt er met de server contact gemaakt en het script/commando uitgevoerd. Nadelen:
• We moeten eerst het paswoord aan de eindgebruiker opvragen. • Het paswoord moet als gewone tekst over het netwerk gestuurd worden.
5.3.2 Uitvoeren via aangemaakt script Deze methode kan door alle methodes gebruikt worden. Het komt er gewoon op neer dat we met Tcl een Bash of ander Tcl script genereren met de uit te voeren commando's en dit dan uitvoeren op de server.
47
Karel Nijs
Automatisatie van ASIC vericatie
5.3.3 Besluit Nadat alle mogelijkheden afgewogen en bestudeerd zijn, hebben mijn interne promotor, Joachim, en ik besloten om de client-server communicatie, ie. het doorsturen van de commando's naar de remote server voor uitvoer, te implementeren als Tcl C extensie. Om deze client-server communicatie eenduidig volgens een vast patroon te laten verlopen, gaan we een eigen communicatieprotocol ontwerpen. Dit communicatieprotocol gaan we op twee manieren implementeren:
• onbeveiligd, als plain text communicatie; • beveiligd, gebruik makend van de SSL bibliotheek. Eerst gaan we van het protocol de plaatsing, de werking en de implementatie bespreken. Vervolgens wordt de beveiliging van de communicatie besproken.
Plaats in n-tier model
Figuur 5.2:
Plaats van de netwerklaag in het n-tier model
Bij het ontwerpen van een applicatie probeert men met verschillende lagen, tiers, te werken en zo delen van het programma te scheiden.
48
Karel Nijs
Automatisatie van ASIC vericatie
Dit heeft als voordeel dat je de verschillende tiers onafhankelijk kunt opbouwen en dat er in verschillende fasen gewerkt kan worden. Een standaardverdeling is de 3-tier verdeling: je deelt je applicatie op in een Application Tier, Business Logic Tier en Database Tier. De opdeling van dit project kan ook in 3 delen: Application Tier, Business Logic Tier en Network Tier. Omdat Tcl echter een geïnterpreteerde taal is zonder object hiërarchie kunnen we de Application en Business Logic Tier niet volledig scheiden: er zit immers een deel van de programmalogica verweven in de Tcl commando's die de GUI opbouwen4 . De Business Logic en Network Tier kunnen we wél volledig scheiden: we gaan via de ontworpen Tcl C extensie de netwerklaag rechtstreeks aanspreken. Een voorbeeld hiervan vind je in Codefragment 2.
5.4 Protocol Het protocol, wat we voor de eenvoud asicPROTO genoemd hebben, beschrijft nauwkeurig en eenduidig de communicatie tussen client en server. Alle client-server communicatie moet volgens dit protocol lopen en wordt afgebroken wanneer dit niet zo is. Er worden afspraken gemaakt voor:
• het openen en sluiten van de verbinding, • het doorsturen van commando's, • het uitvoeren, opvolgen en annuleren van processen, • de volgorde en nummering van berichten.
5.4.1 Plaats in OSI-model De plaats van het asicPROTO is afhankelijk van de onderliggende implementatie ervan: zoals eerder gezegd, hebben we het protocol op twee manieren geïmplementeerd: onbeveiligd (plain text ) en beveiligd (SSL). Bij de onbeveiligde implementie wordt het asicPROTO protocol bovenop de TCP laag geïmplementeerd (zie Figuur 5.3). Op deze manier kunnen we gemakkelijk gebruik maken van de API voor POSIX sockets. Wanneer het asicPROTO werkend is met POSIX sockets, kunnen we verder overgaan naar de beveiligde implementatie met SSL (zie Figuur 5.4). 4
Een goed voorbeeld hiervan is de opbouw en werking van de keuzelijsten op het Check Specications tabblad
49
Karel Nijs
Automatisatie van ASIC vericatie
Figuur 5.3:
Figuur 5.4:
Plaats van het onbeveiligde protocol in het OSI-model
Plaats van het beveiligde protocol in het OSI-model
Een voorbeeld van alle berichten en hun mogelijke code kan je vinden in Tabel 5.1. De beheerder kan eventueel deze codes zelf wijzigen, hun waarde is niet van belang (consistentie daareentegen weer wel).
5.4.2 Verschillende statussen Uitleg bij Figuur 5.5: (a) Het opstarten van de communicatie verloopt telkens op volgende manier en moet voor elke guur b, c, d en e opnieuw uitgevoerd worden: 1. De client contacteert de server. 2. De server antwoordt hem en stuurt een
seed x.
3. De client bevestigt de ontvangen seed door een acknowledge bericht te sturen met een transformatie van die seed. 4. De server bevestigt het ontvangen bericht door een acknowledge bericht te sturen met een transformatie van het vorige sequentienummer.
50
Karel Nijs
Automatisatie van ASIC vericatie
Message
Code
HELLO ACK EOC NACK CMD EXEC PID CANCEL
0 1 2 3 4 5 6 7 Tabel 5.1:
Protocolberichten
Nu weten client en server dat de seed juist uitgewisseld is en de volgende berichten met correcte sequentienummers verzonden kunnen worden. De transformatie van de seed is cruciaal en wordt verder beschreven in 5.4.3. In de verdere bespreking van de verschillende statussen gaan we geen aandacht meer besteden aan sequentienummers. (b) Het afsluiten van de communicatie: 1. De client stuurt een EOC5 bericht naar de server. 2. De server bevestigt ontvangst van het EOC bericht. Nu kunnen de client en server de overeenkomende sockets sluiten en de resources vrijgeven. Ik wil even opmerken dat het eigenlijk niet nodig is deze stap uit te voeren: wanneer we langs de clientzijde de verbinding zouden beëindigen mbv. de POSIX close() functie, wordt er door het onderliggende TCP protocol een EOF bericht gestuurd naar de server. (c) Het doorsturen en uitvoeren van een commando: 1. De client stuurt een CMD bericht samen met het uit te voeren commando naar de server. 2. De server bevestigt ontvangst van het CMD bericht. 3. De client geeft de server de opdracht het commando uit te voeren mbv. het EXEC bericht. 4. De server voert het commando uit en bevestigt de ontvangst van het EXEC bericht door een PID bericht te sturen met het process id van het commando in uitvoering. Deze stap kan je ook op verschillende manieren implementeren: 1. We sturen een CMD bericht naar de server. Deze voert het bijgevoegde commando uit en stuurt onmiddellijk een PID bericht met bijhorende process id naar de client. 5
EOF is een reeds gereserveerd woord in C++
51
Karel Nijs
Automatisatie van ASIC vericatie
2. Omdat een commando lang kan worden, kan de situatie voorkomen dat we dit niet in één keer kunnen doorsturen. Een mogelijke oplossing hiervoor is eerst het aantal commando's doorzetten met een NUM bericht en vervolgens elk commando met een CMD bericht naar de server doorzenden. De server voegt de commando's samen en wacht al dan niet op het EXEC bericht alvorens een PID bericht terug te zenden naar de client. In praktijk komt deze situatie echter niet voor (zie 6.3.4). (d) Controleren of een proces nog in uitvoering is: 1. De client stuurt een PID bericht samen met het te controleren process id. 2. Het proces is nog in uitvoering en de server antwoordt de client met een ACK. Voor de werking hiervan verwijzen we (opnieuw) naar Codefragment 5.2. Wanneer het starten van het proces mislukt was, wordt het ACK bericht vergezeld van een negatief PID. Aan de hand van dit negatief PID kan de client het besluit trekken dat het commando nooit is kunnen starten en dit doorgeven aan de GUI. (e) Controleren of een proces nog in uitvoering is (2): 1. De client stuurt een PID bericht samen met het te controleren process id. 2. Het proces bestaat niet (meer) en de server antwoordt de client met een NACK.
5.4.3 Sequentienummers Elk bericht dat verstuurd wordt, is vergezeld van een sequentienummer. Aan de hand van dit sequentienummer kan de ontvanger van het bericht controleren of het aangekomen bericht een antwoord is op het bericht dat hij gestuurd heeft of een volgende bericht in de reeks is. Wanneer de ontvanger merkt dat het sequentienummer niet overeenkomt met het volgende nummer dat hij berekend heeft, verwerpt (negeert) hij het binnengekomen bericht. De generatie van sequentienummers moet voor client en server hetzelfde zijn. Daarom wordt er met het HELLO antwoord van de server een seed meegestuurd. Met deze seed hebben we een beginwaarde om onze sequentienummers mee te berekenen. De berekening van het volgende sequentienummer gebeurt met de PSgen klasse die aan de verbinding meegegeven wordt (zie 6.3.2). Het algoritme hiervoor steunt op the Sieve of Eratosthenes 6 en gaan we hier niet verder uitleggen. Het is belangrijk dat de generatie van de sequentienummers niet te zwaar is, anders gaat dit de client-server interactie aanzienlijk vertragen en dit is zeker niet gewenst. 6
http://www.archimedes-lab.org/primOmatic.html
52
Karel Nijs
Automatisatie van ASIC vericatie
Het principe van de sequentienummers heeft gelijkenis met het TCP protocol, doch zorgt TCP ervoor dat elk bericht zeker aankomt. Het is niet onze taak dit nogmaals te voorzien: als een onderliggende laag iets implementeert, mogen we er op rekenen dat dit correct werkt. Wanneer we gaan communiceren via het SSL protocol is het zelfs helemaal niet meer nodig om sequentienummers mee te sturen: het onderliggende SSL protocol zorgt dan immers voor authenticatie en condentialiteit. We gaan echter in onze applicatie wél sequentienummers gebruiken, ook met SSL. Op deze manier hebben we een beter algemeen overzicht en kunnen we aan de hand van dit nummer makkelijk beslissen of het ontvangen bericht verder behandeld moet worden of niet.
5.5 Beveiliging 5.5.1 Vooraf Vooraleer we de beveiliging van ons communicatie protocol kunnen implementeren, moeten we weten wat de risico punten zijn:
• Wat moet er precies beveiligd worden?
visie van de gebruiker, visie van de ontwerper. • Is de beveiliging nodig? • Hoe serieus moeten we deze beveiliging nemen? • Wat zijn de zwakke punten van de van gemaakt worden?
on beveiligde applicatie en hoe zeer kan hier misbruik
• Hoe kunnen we deze beveiliging testen? Pas wanneer we een antwoord hebben op al deze vragen kunnen we zeggen dat we een volledige analyse van de beveiliging hebben.
5.5.2 Doorgeven commando's van de Tcl GUI naar de Tcl C extensie Dit is een belangrijke stap die zeker goed beveiligd moet worden. Stel dat de Tcl C extensie vrij toegankelijk is en iedereen er gebruik van zou kunnen maken. Op deze manier werken we net bovenstaand probleem in de hand: je kan dan op een makkelijke manier een eigen Tcl GUI schrijven die een slecht commando doorstuurt. Dit is een redelijk ernstig probleem. Vanaf dat de extensie het commando van de Tcl GUI gekregen heeft, verloopt alles immers op een beveiligde manier: de server kan vanaf dit punt geen onderscheid meer maken tussen een gebruiker en een mis bruiker. Dit natuurlijk allemaal in veronderstelling dat het onderliggende protocol veilig en correct is.
53
Karel Nijs
Automatisatie van ASIC vericatie
Oplossing De oplossing is redelijk eenvoudig: we plaatsen de extensie in een directory waar asicgui eigenaar van is en we veranderen de rechten van de map en inhoud ervan. Wanneer we personen van dezelfde groep (asicgui) enkel uitvoerrechten geven, kunnen ze nooit de Tcl scripts lezen en te weten komen waar de extensie zich bevindt. Mocht men nog de plaats van de extensie te weten komen, kunnen alleen gebruikers die tot de asicgui groep behoren er misbruik van maken. Om deze methode nog extra te beveiligen, spreken we een passphrase af die doorgegeven moet worden van de Tcl GUI naar de C extensie. Omdat niemand van de gebruikers de Tcl scripts noch de originele en ongecomprimeerde C++ code kan lezen, is deze methode redelijk waterdicht. Omdat het paswoord zichtbaar zou kunnen zijn in de gecompileerde C++ code hebben we er voor gekozen dit paswoord niet letterlijk in de code op te nemen. We gaan wel gebruik maken van een algoritme dat dit paswoord genereert. Dit algoritme wordt zowel in Tcl als C++ geïmplementeerd.
Experiment Voor dit experment hebben we het Tcl programma hack.tcl aangemaakt dat probeert misbruik te maken van onze C extensie en een obscuur commando7 door te sluizen naar de server. 1 2 3 4 5
#!/usr/bin/tixwish8.3 -f load ./exp_1/my_socket[info sharedlibextension] set cmd1 "startCheck&; startCheck& ; ..." ::nw_service::my_socket send localhost:5001 $cmd1 exit
Allereerst wijzigen we de toegang tot de directory waar het programma zich in bevindt (zie Appendix C). De hacker kan dan, in veronderstelling dat hij het pad naar de module weet, nog altijd misbruik maken van de C module: 1 2 3 4 5
$ ./hack.tcl log of 26-10-2005 16:02:33 DBG > Connecting to localhost... DBG > Connected with 127.0.0.1:5001! ...
Nu passen we ons origineel Tcl script (dat de extensie oproept) een klein beetje aan zodat we een parameter meegeven8 . 1
char *cmd = Tcl_GetStringFromObj(objv[SAVE], NULL);
2 7 8
Als je weet dat een check 2 dagen kan duren, is het starten van drie zo'n checks ook een obscuur commando Natuurlijk moet de controle van deze parameter ook in de C extensie opgenomen worden
54
Karel Nijs
3 4 5 6
Automatisatie van ASIC vericatie
if( pphrase != genPass() ){ Tcl_AddErrorInfo(interp, "Invalid passphrase!"); return TCL_ERROR; }
Als we dan ons misbruik Tcl script proberen uit te voeren: 1 2 3 4 5
$ ./hack.tcl log of 26-10-2005 16:41:18 Error in startup script: Invalid passphrase! invoked from within ...
Hoe veilig deze eerste stap precies is, hangt af van de sterkte van het codewoord en de omgang met source code in het bedrijf.
Integriteit van de (bron)code Het is belangrijk dat we de integriteit van de bron- en uitvoerbare code kunnen garanderen: als iemand de broncode zou kunnen krijgen, is het codewoord makkelijk aangepast en ligt de weg naar misbruik open. Hiervoor kunnen we gebruik maken van een SHA1 hash (MD5 gaat ook, maar wordt als onveilig beschouwd (7, Chapter 1)). Een nadeel van het gebruik van een hash is dat de gegenereerde hash waarde extreem gevoelig is voor een man in the middle aanval: wanneer iemand simpelweg de hash waarde van een slecht programma vervangt door deze van een goed werkend programma, kan de tester nog altijd niet zeker zijn van de integriteit. Een andere oplossing is het gebruik van een digitale handtekening (DSA): hiermee kunnen we een handtekening genereren van de SHA1 hash van een stuk data. De generatie van de handtekening gebeurt met behulp van een private sleutel en iedereen kan deze met de bijhorende publieke sleutel veriëren. De signature aanmaken: 1
2
$ openssl dgst -sha1 -out runasicgui.sig -sign pkey.pem -rand /dev/urandom runasicgui Enter pass phrase for client.key:
De handtekening veriëren: 1 2 3
$ openssl dgst -sha1 -prverify pkey.pem -signature runasicgui.sig runasicgui Enter pass phrase for client.key: Verified OK
We moeten volgende veronderstellingen maken:
55
Karel Nijs
Automatisatie van ASIC vericatie
• we vertrouwen de gebruiker die de originele hash berekend en getekend heeft; • we zijn er zeker van dat niemand toegang heeft tot dit certicaat zodat de hash niet opnieuw berekend en getekend kan worden. We zouden telkens voor het opstarten van de server service deze handmatige controle kunnen uitvoeren. Omdat dit echter in de praktijk niet gedaan wordt, is het makkelijker indien we dit proces kunnen automatiseren. We kunnen het op twee manieren oplossen: 1. Bij opstarten voeren we in een Bash script het openssl rsautl commando uit en nemen een beslissing aan de hand van de terugkeerwaarde van dit commando. 2. Bij opstarten implementeren we de C++ versie van het openssl rsautl commando en controleren we in C++ of de hash overeenkomt. Deze manier vermijdt een extra Bash script tijdens het opstartproces. Het algoritme zou op volgende manier geïmplementeerd kunnen worden: 1 2
laad_certificaat() controleer_handtekening()
3 4 5 6 7
if ( ok ) start_service() else geef_fout()
Codefragment 5.5:
Valideren handtekening bij opstarten applicatie (pseudocode)
5.5.3 Verkeer tussen client en server Risico's Het sturen van de commando's tussen client en server kan op verschillende manieren gevaarlijk zijn:
• eavesdropping, • spoong, • replay.
Eavesdropping Eavesdropping is luisteren naar de communicatie tussen de verschillende hosts. Deze methode wordt gebruikt door hackers om informatie af te leiden uit de communicatie zoals bv. als clear text doorgestuurde paswoorden (standaard FTP). We kunnen dit voorkomen door de communicatie tussen client en server te encrypteren.
56
Karel Nijs
Automatisatie van ASIC vericatie
Spoong Spoong is wanneer iemand zich uitgeeft voor iemand anders. Wanneer de server een pakket ontvangt, mogen we er niet altijd van uitgaan dat dit pakket van de echte client afkomstig is. Een misbruiker kan namelijk het netwerkverkeer geanalyseerd hebben, het protocol (en/of encryptie) doorgrond en op basis hiervan zelf een bericht naar de server gestuurd hebben. Wanneer we gebruik maken van encryptie is dit al wat moeilijker, maar dit probleem oplossen is zeker een interessante uitdaging. Hier komen onze sequentienummer van pas (zie 5.4.3). Wanneer een misbruiker een bericht zou willen sturen naar de server in de hoop dat deze het zal uitvoeren, zal hij niet alleen de encryptie moeten doorbreken: hij moet ook nog een antwoord sturen met de juiste nummerverhoging (en hiervoor dus over hetzelfde algoritme en seed beschikken).
Replay Een andere mogelijke aanval is replay. We spreken van een replay aanval wanneer eenzelfde bericht opnieuw naar de server gestuurd wordt in de hoop dat het uitgevoerd wordt. Deze aanval lijkt onschuldig, maar we willen de lezer er aan herinneren dat de uitvoering van een check langdurig en processorintensief is. We beveiligen ons echter tegen replay op dezelfde manier als tegen spoong: door sequentienummers te gebuiken. Aangezien de server een bericht met een fout sequentienummer verwerpt, is er geen mogelijkheid tot replay: een juist vorig sequentienummer is namelijk een fout huidig sequentienummer.
Oplossing Om eavesdropping en spoong tegen te gaan, moeten we een oplossing zoeken die zowel de authenticiteit van de communicatie partners garandeert als de doorgestuurde data encrypteert. Na enig opzoekwerk, zowel op het Internet als in (13), hebben we een aantal oplossingen hiervoor gevonden:
• Internet Protocol Security IPsec, • Secure Socket Layer SSL, • Transport Layer Security TLS9 . IPsec is een protocol dat op de netwerklaag van het OSI-model werkt, terwijl SSL en TLS op de transportlaag werken. 9
Eigenlijk is TLS gelijkwaardig aan SSLv3.1 (zie 7.1.1).
57
Karel Nijs
Automatisatie van ASIC vericatie
Om een keuze te maken tussen deze drie hebben we (13, Chapter 21) geraadpleegd. Hieruit kunnen we opmaken dat IPsec en SSL dezelfde garanties qua beveiliging en authenticiteit stellen. Het in praktijk brengen van deze technologieën is wel een andere uitdaging: IPsec moet in de kernel gecompileerd worden en vervolgens moeten we security assosiations deniëren om een beveiligde verbinding te leggen tussen twee hosts. SSL/TLS voorziet beveiliging op applicatie niveau. Beide methodes zijn transparant voor de bovenliggende applicaties. Dit wil zeggen dat als je volgens een n-tier model werkt, je niet hoeft te weten hoe de beveiliging geïmplementeerd is: je kan gewoon de beveiligde onderliggende lagen gebruiken. Wanneer we echter via BSD sockets willen communiceren, is dit maar een halve waarheid: aangezien we zelf onze sockets gaan moeten aanmaken, gaan we ze ook zelf moeten beveiligen. Ook de mogelijkheden van de servers beperken onze opties: aangezien we (nieuwe) extra software moeten vermijden, moeten we een oplossing zoeken die ofwel al aanwezig is op de server, ofwel niet geïnstalleerd moet worden. Omdat het ons interessant leek om verder te blijven werken met sockets hebben we ervoor gekozen om de beveiliging te implementeren met SSL sockets. De bespreking van de implementatie kan je terug vinden in sectie 7.1.
5.5.4 Server service op poort x Om te kunnen communiceren met clients moet de server luisteren op een bepaalde poort. Vooraleer iemand misbruik kan maken door een bericht naar de server te sturen, moet hij weten op welke poort de service beschikbaar is. We kunnen als maatregel nemen dat wanneer er een bericht toekomt, dat niet aan het protocol beantwoordt, we niets terug sturen. Deze maatregel zou echter geen zin hebben: als de misbruiker connectie maakt met onze server op een bepaalde poort zal het TCP protocol zowieso een antwoord sturen en weet de misbruiker dat er een service actief is op die bepaalde poort. Ook niets antwoorden is geen oplossing, want als er geen service draait op de poort, dan stuurt (het OS van) de host een bericht dat connectie op die poort niet mogelijk is. Er zijn vele port scanners waarmee dit gedetecteerd kan worden (zie (3)): nmap, strobe, netcat, ... Met andere woorden: het heeft geen zin om een ingewikkelde manier te bedenken voor het verbergen van de poort als er zoveel tools bestaan (die op verschillende wijze werken) om openstaande poorten te ontdekken.
58
Karel Nijs
Automatisatie van ASIC vericatie
5.5.5 Uitvoeren van commando's Bij het uitvoeren van de commando's is er geen bekend risico. De commando's worden door de server in een gesloten omgeving opgevangen (een gecompileerd C programma) en van hieruit ook uitgevoerd. De uitvoer van de commando's wordt, zoals eerder besproken, geredirect naar een bestand (zie 5.5.6). Als het beveiligen van de vorige stappen goed geïmplementeerd is, is er hier geen probleem.
5.5.6 Output van commando's De uitvoer van een check kan behoorlijk veel output genereren, zowel naar het scherm toe als in de vorm van les. Daarom laten we in de Tcl GUI de gebruiker zelf zijn werkdirectory10 kiezen: daarin komen dan de resulterende les en ook eventueel de naar le(s) geredirecte output.
5.5.7 Uitvoeromgeving Met behulp van het chroot commando kan je voor een bepaald proces een chroot jail instellen. Zo'n cel denieer je door je root directory te verplaatsten (change root) naar een andere directory. In deze directory ga je dan een *nix root equivalent maken: er worden enkel de benodigde bestanden gekopieerd om de omgeving te laten werken. Een chroot jail heeft het voordeel dat je niets mis kan doen omdat je in het slechtste geval enkel de celomgeving zou vernielen. Dit is handig voor onze server service. Wanneer deze immers in een cel kan draaien, zijn de gevolgen minder ingrijpend wanneer een kwaadwillige gebruiker een aanval zou doen. De server is echter nog steeds gevoelig voor DoS aanvallen omdat we van dezelfde systeembronnen gebruik blijven maken. Deze implementatie heeft echter zoveel beperkingen dat het niet mogelijk is deze in praktijk toe te passen. Ik verklaar nader. Opdat alle gewenste EDA's aanwezig zouden zijn, moeten we deze programma's (meestal binaire bestanden) kopiëren naar de nieuwe root. Ook een basisset Shell tools, de tools die de EDA's nodig hebben en alles voor de opvolging ervan moeten beschikbaar zijn. Dit kopiëren is op zich nog niet zo'n groot probleem: er zal enkel iemand verantwoordelijk moeten zijn om nieuwe versies te installen wanneer deze uitkomen (normaal eens per jaar). Een groter probleem is de resterende functionaliteit: een gebruiker wil namelijk een vericatie van een GDS-le tegen de bijhorende rules le uitvoeren. Deze les zijn (waarschijnlijk) nog niet beschikbaar in de chroot omgeving. Vanuit de chroot kunnen we niet naar deze paden verwijzen, net omdat de root verplaatst is. 10
Opm: het is belangrijk dat het programma schrijf- en uitvoerrechten heeft in de opgegeven werkdirectory.
59
Karel Nijs
Automatisatie van ASIC vericatie
Om dit op te lossen zouden voor dat de check start alle nodige les verplaatst moeten worden naar deze chroot omgeving. Omdat een GDS-le tot 1 GB groot kan zijn, zou dit kopiëren nefast zijn voor de performantie van de applicatie. In tegenstelling tot het grote voordeel qua veiligheid verbonden aan deze methode lijkt het gebruik er van praktisch niet haalbaar.
60
Karel Nijs
Automatisatie van ASIC vericatie
61 Figuur 5.5:
Verschillende statussen van asicPROTO
Hoofdstuk 6
Netwerklaag: implementatie 6.1 Inleiding De implementatie bleek niet zo evident te zijn als verwacht: ik had al enige ervaring met C en C++, doch heb ik nooit een grootschalig project moeten ontwikkelen met deze talen.
6.1.1 IDE Aanvankelijk zijn we begonnen in een gewone tekstverwerker (Kate), maar al gauw bleek dat het niet haalbaar was dit volledig project te ontwikkelen met zo'n elementaire programmeeromgeving (mag je Kate wel een programmeeromgeving noemen?). Na zoeken op het Internet hebben we de KDevelop IDE ontdekt. Deze bleek al mijn eisen te vervullen: intellisense, code aanvulling, projectmanagement, enz.
6.1.2 C++ debuggen Om de implementatie te testen, hebben we een script gebruikt1 dat de server extreem belast: vele clients (> 50) die om de seconde de server contacteren om bijvoorbeeld de server informatie. Deze situatie zal nooit voorkomen in het dagelijks gebruik (de afdeling heeft maar een veertigtal werknemers), maar is wel een mooie test voor de mogelijkheden van de server. Tijdens deze testen zijn we vele hindernissen tegen gekomen: geheugenfouten op de gekste plaatsen, geheugenlekken in standaardbibliotheken, std::set die problemen had met null waardes, ... We hadden een goede debugtool nodig. Hiervoor hebben we een combinatie gebruikt van:
• de -Wall -g command line parameters van GNU GCC: deze geven alle en duidelijkere foutmeldingen; • strace: een handige tool die je het programma welke actie een fout geneert; 1
Met dank aan mijn interne promotor, Joachim
62
live laat meevolgen. Je kan precies zien
Karel Nijs
Automatisatie van ASIC vericatie
• Valgrind: een programma om geheugenlekken mee op te sporen. Dankzij Valgrind hebben we de meeste problemen kunnen oplossen.
6.1.3 Geheugenfouten en -lekken Een geheugenfout merk je onmiddellijk tijdens uitvoering: het programma eindigt dan met een Segmentation Fault of Aborted melding. Een geheugenlek is echter een groter probleem. Een lek merk je niet onmiddellijk, maar leidt ook onvermijdelijk tot een crash. Een voorbeeld: omwille van compatibiliteitsredenen hebben we er voor gekozen de inet_ntoa() functie te gebruiken in plaats van inet_ntop() (merk de laaste letter op). Deze functies worden gebruikt om het netwerkadres van een computer om te zetten van netwerk- naar presentatienotatie. Valgrind geeft aan dat deze inet_ntoa() functie bij elke connectie 4 bytes lekt. Stel dat je een geheugen van 256 MB hebt en er om de seconde 50 clients connecteren, dan kan je applicatie ongeveer 6u draaien alvorens we een Aborted error ontvangen omdat er geen geheugen kan vrij gemaakt worden voor de objecten die de client afhandelen. De servers bij IMEC hebben natuurlijk een veelvoud meer aan geheugen, maar inet_ntoa() is niet de enige functie die geheugen lekt2 en het is de bedoeling dat de server service voor eeuwig blijft draaien.
6.1.4 HP-UX compilatie De netwerklaag is bijna volledig en continu ontwikkeld op een GNU/Linux 32bit platform. De servers bij IMEC zijn echter 64bit GNU/Linux en 64bit HP-UX. Omdat we dit op voorhand wisten, hebben we geprobeerd zo veel mogelijk met POSIX compatibele functies te werken. POSIX functies hebben eenzelfde aanroep en resultaat, maar kunnen anders geïmplementeerd worden. In de code kan je echter op sommige punten architectuurspecieke implementaties zien; namelijk niet alle gebruikte functies voldoen aan de POSIX compatibiliteitseis. Een voorbeeld vind je in de ASICserver::server_info() functie: hier vragen we de systeeminformatie op waarvan de implementatie platformafhankelijk is. Deze problemen hebben we proberen op te lossen met compiler directives. Verder bleek de geïnstalleerde GNU GCC 2.95 compiler niet compatibel met HP-UX versie 11.0. Een oplossing hiervoor was compilatie met GNU GCC 4.0.2 Ook de HP-UX conversie van de OpenSSL API hebben we moeten compileren installeren in de projectaccount. Met deze HP-UX 64bit bibliotheken kunnen we ons programma compileren. Het compileren op HP-UX is uiteindelijk toch gelukt (er is hier veel tijd in gekropen). Het programma geeft echter vele geheugenfouten in de OpenSSL functies zelf! Omdat we deze niet 2
Op sommige punten geeft Valgrind ook lekken aan in het
63
ostringstream
type en de
sscanf()
functie
Karel Nijs
Automatisatie van ASIC vericatie
kunnen editeren, of zeker toch niet de tijd er voor beschikbaar hebben, werkt de applicatie op moment van schrijven nog niet op het HP-UX 11.0 platform.
autoconf en automake De autoconf en automake tools zijn er om Makeles te genereren zodat de applicatie overgedragen kan worden naar systemen met verschillende architecturen. Ik heb helaas geen tijd meer gehad om de werking van deze tools volledig te doorgronden. Hierdoor is de installatieprocedure, doch ze maar éénmaal uitgevoerd moet worden, tamelijk ingewikkeld.
6.1.5 API De DOxygen tool hebben we gebruikt om de API te genereren. In vergelijking met de AutoDoc tool is DOxygen vele malen beter en meer overzichtelijk, zonder enige aanpassingen. De hele C++ code is gedocumenteerd met JavaDoc commentaar, waarmee DOxygen overweg kan. Tijdens de ontwikkeling van de netwerklaag hebben we er extra op gelet deze documentatie zo goed mogelijk in te vullen, anders is het project niet geschikt voor latere opvolging, onderhoud en/of uitbreiding. De hele code is in het Engels gedocumenteerd omdat er vele verschillende nationaliteiten bij IMEC werken en Engels de voertaal is.
6.2 Namespaces en utilities Waar nodig hebben we gebruik gemaakt van C++ namespaces. Achteraf bekeken, hadden we gerust alle klassen in namespaces kunnen zetten. Utilities of gemeenschappelijk gebruikte functies hebben we geplaatst in de aparte namespaces Networkfunctions en SSLfunctions. Deze twee klassen herimplementeren standaard bibliotheekfuncties zoals bv. gethostbyname(), gebruikt door de PlainConn en SSLconn klassen. Het gebruik van deze methode is aangeraden in (10). Op deze manier kunnen we foutopvanging mogelijk maken volgens ons model (zie 6.3.1). Ook een groot voordeel is dat de algemene code er duidelijker op wordt. Wanneer we gebruik zouden maken van de bibliotheekfuncties met behulp van traditionele foutafhandeling (6, Hoofdstuk 14), ziet een aanroep er ongeveer zo uit: 1 2
struct hostent* host = gethostbyname( hname ); if(host == NULL)
64
Karel Nijs
Automatisatie van ASIC vericatie
return -1;
3
Codefragment 6.1:
Traditionele foutafhandeling
Wanneer we gebruik maken van onze utility klasse(n) krijgen we volgende situatie: 1
struct hostent* hoststruct = Networkfunctions::Gethostbyname( hname , dbg, 2 ); Codefragment 6.2:
Foutafhandeling volgens ons Debug model
Bij de aanroep wordt een Debug object meegegeven en het gewenste loglevel. Wanneer er een fout zou optreden bij naamresolutie, gaan de Debug klasse een level 2 fout generenen, die dan weer een ASICexception werpt. We moeten nu enkel in ons hoofdprogramma deze ASICexception opvangen. Dit opgevangen gebeurt (bij ons) niet in de PlainConn klasse, maar in de klasse die een object wil aanmaken van de PlainConn klasse. Bij het optreden van een level 2 fout mag er immers geen verder gebruik gemaakt worden van dit PlainConn object. De implementatie van de Networkfunctions::Gethostbyname() functie ziet er als volgt uit: 1 2 3 4 5 6 7 8 9
10
/** * tries to create a socket * @param name the host name * @param dbg handler for errors * @param loglevel defines the "seriousness" of failure, if so * @return the hosteny structure * @throws ASICexception */ struct hostent* Networkfunctions::Gethostbyname(const char *name, Debug *dbg, int loglevel) { struct hostent* host = gethostbyname(name);
11
if(host == NULL) { ostringstream out; out << "Unable resolve host name '" << *name << "'"; dbg->write( out.str(), __FUNCTION__, loglevel ); }
12 13 14 15 16 17
return host;
18 19
} Codefragment 6.3:
Networkfunctions::Gethostbyname() functie
Dit principe is toegepast voor haast alle functies waarvan de terugkeerwaarde gecontroleerd moet worden. We verwijzen hiervoor naar de API van de Networkfunctions en SSLfunctions namespaces. Voor de implementatie van Networkfunctions::read() en Networkfunctions::write() verwijzen we naar Sectie 7.3, daar deze grotendeels overeenkomt met de SSLfunctions::read() respectievelijk SSLfunctions::write() implementatie. De utility namespaces worden in aparte C++ header les gedenieerd. Zou je dit niet doen,
65
Karel Nijs
Automatisatie van ASIC vericatie
treden er zeker fouten op tijdens compilatie omdat meerdere bestanden dezelfde functies willen includeren.
6.3 Klassenmodel 6.3.1 Debug klasse De Debug klasse werkt op een gelijkaardige manier als de Tcl Debug module. De Tcl Debug module is namelijk gebaseerd op deze klasse. Bij het aanmaken van een Debug object heb je de keuze naar welk kanaal de log- en/of foutberichten gestuurd worden. Je kan hier werken met standaard le descriptors (gehele getallen) of paden naar logbestanden. Er is de mogelijkheid om in hetzelfde bestand zowel de log- als foutberichten te melden.
Gebruik syslog Om gebruik te maken van de syslog daemon, wordt de syslog() functie geïmplementeerd. 1 2 3
//open systemlogger openlog( LOG_PROGID, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1 ); syslog( LOG_NOTICE, "Program started by User %d", getuid() ); Codefragment 6.4:
Gebruik syslog()
Door de openlog() functie te gebruiken, kunnen we zelf de naam speciëren die voor onze applicatie in syslogd gebruikt wordt. Wanneer we de Debug klasse gebruiken met le descriptors wordt de LOG_CONS optie niet toevoegd, want anders zouden we dubbele uitvoer krijgen naar de console. Het verschil met de Tcl Debug module hier is wanneer een level 2 fout (zie 3.5) optreedt. Een level 2 fout wordt namelijk wél aan syslogd gemeld, andere fouten bereiken de syslog daemon niet. Op deze manier wordt het systeemlog niet vervuild. Bij een level 2 fout wordt er een ASICexception geworpen. Deze moet opgevangen worden in een bovenliggende functie om goed verloop van het programma te garanderen.
6.3.2 PSgen klasse Om replay-aanvallen tegen te gaan en om de client-server interactie te vergemakkelijken, hadden we besloten om een pseudorandom sequentienummering te gebruiken. Omdat deze sequentienummering vooral snel ter beschikking moet kunnen zijn, hebben we geen zwaar wiskundig algortime gekozen. De PSgen klasse laat toe om zowel een nieuw sequentienummer, als het laatste op te vragen. Op deze manier kunnen we indien nodig de generator meerdere keren raadplegen voor hetzelfde nummer.
66
Karel Nijs
Automatisatie van ASIC vericatie
6.3.3 Client-server model Voor we de specieke client- en serverimplementaties gaan bespreken, leggen we best eerst grondig het gebruikte client-server model uit. Deze sectie is dan ook een belangrijk onderdeel als je de rest goed wilt kunnen volgen. Zoals je in Figuur 5.2 kon zien, is de onderste laag van ons n-tier model, de netwerklaag, ook nog eens opgedeeld in twee delen. Aan de clientzijde wordt bijvoorbeeld het hele ASICproto protocol afgehandeld door de ASICclient, terwijl deze gewoon de te verzenden berichten doorgeeft aan de onderliggende netwerk client. Binnenkomende berichten worden dan weer doorgegeven van netwerkclient naar ASICclient. Aan de serverzijde vind je een gelijkaardige situatie terug. De ASICclient kan dus communiceren met de ASICserver zonder dat hij iets af weet van de onderliggende implementatie. Hierdoor is het mogelijk om willekeurig onderliggende laag te gebruiken. Dit hebben we dan ook toegepast met het ontwikkelen van dit eindwerk. Aanvankelijk hebben we het hele protocol geïmplementeerd zonder beveiliging op het laagste niveau. Wanneer de client-server interactie op dit niveau functioneel was, hebben we de klassen geschreven om de SSL sockets te implementeren. Omdat het objectmodel van C++ verschilt van dit van Java hebben we enkele trukjes moeten uithalen om dezelfde functionaliteit te kunnen bereiken.
6.3.4 Socketlaag van de netwerklaag Het is misschien best de bespreking te starten op het elementairste niveau. Er zijn twee soorten connecties die we gebruiken: een plain text connectie en een SSL connectie, respectievelijk geïmplementeerd door PlainConn en SSLconn.
IConnection interface De PlainConn en SSLconn klassen breiden de IConnection klasse uit. IConnection is een abstracte klasse en dus mogen geen er objecten aangemaakt worden van deze klasse. Je kan de IConnection klasse op volgende manier gebruiken: 1 2
//make connection objects IConnection *sconn;
3 4 5 6 7 8
if( useSSL) { sconn = new SSLserver(recv_sd, client, dbg); } else { sconn = new PlainServer(recv_sd, client, dbg); } Codefragment 6.5:
Gebruik van abstracte klasse IConnection
67
Karel Nijs
Automatisatie van ASIC vericatie
Figuur 6.1:
IConnection abstracte klasse
IConnection was origineel ontworpen als interface (vandaar de 'I' in de naam), maar is in de loop van de ontwikkeling een abstracte klasse geworden. Een beter ontwerp zou deze IConnection interface behouden hebben en de abstracte Connection klasse deze laten implementeren. Ook van de PlainConn en SSLconn klassen kan je geen objecten aanmaken. De reden hiervoor is de specieke implementatie vereist voor de hosts. PlainConn en SSLconn werken de meer socket specieke functies uit zoals zenden/ontvangen van berichten en het afsluiten van de socket. De intialisatie en conguratie van de socket zelf is eerder host speciek : er zijn hier relatief grote verschillen voor clients en servers (een server moet namelijk binden en ontvangen, terwijl een client enkel moet connecteren. Met behulp van de IConnection klasse kan er eventueel later een klasse toegevoegd worden die de beveiliging anders implementeert. Het gebruik van de socketlaag is transparant voor de ASICclient en -server. Wanneer IMEC bijvoorbeeld zou willen afstappen van het gebruik van de, redelijk omslachtige, SSL sockets, kunnen ze altijd een CryptConn klasse ontwikkelen. Deze CryptConn klasse zou dan de beveiliging kunnen implementeren volgens een symmetrische encryptiemethode.
68
Karel Nijs
Automatisatie van ASIC vericatie
Figuur 6.2:
Mogelijke implementatie van CryptConn klasse
6.3.5 ASICproto laag van de netwerklaag Deze laag voorziet de feitelijke communicatie volgens het ASICproto protocol. Zowel de client als de server implementeren een apart object van de ASIChost abstracte klasse, respectievelijk ASICclient en ASICserver. De aparte implementatie hier is een gevolg van de interactie volgens het protocol. Wanneer de client zijn connectie start3 (door het sturen van een HELLO bericht), moet de server de connectie op een andere manier starten: hij ontvangt namelijk het bericht, genereert een seed en stuurt deze terug naar de client. Deze verschillen zetten zich door over de gehele communicatie. De methodes van ASIChost, vooraf gegaan door een #, worden door de abstracte klasse zelf geïmplementeerd om dubbele code tegen te gaan. Een voorbeeld hiervan is generateMessage(). Deze functie stelt een bericht, geschikt voor het ASICproto, samen door een eerst een nieuw sequentienummer op te vragen en vervolgens de velden aan elkaar te voegen: 1
512654 @@@ CMD @@@ bash -c " ... " @@@ Codefragment 6.6:
3
ASICproto bericht
De connectie wordt geopend door de onderliggende socket laag
69
Karel Nijs
Automatisatie van ASIC vericatie
Figuur 6.3:
ASIChost abstracte klasse
Alle velden worden afgesloten met een vooraf afgesproken scheidingsteken. Voor verdere uitleg over deze of andere functies verwijzen we naar de API, aanwezig op de CD-ROM achteraan deze thesis.
6.4 Client Bovenstaande bepreking van alle klassen en hun functionaliteit was eerder oppervlakkig. Dit komt omdat de implementatie van de meeste acties afhankelijk is van de communicatiepartner die ze uitvoert. Ik heb daarom de bespreking nog eens opgedeeld in een client en server gedeelte.
6.4.1 ASICclient De ASICclient klasse implementeert de IASICclient interface en breidt de ASIChost abstracte klasse uit. Om gebruik te maken van de onderliggende plain/SSL socketlaag geven we een IConnection object mee tijdens constructie van het ASICclient object. 1 2 3
//create connection objects IConnection* conn; ASICclient* aconn;
4 5 6
if( securityType == argPLAIN ) conn = new PlainClient(server, port, dbg);
70
Karel Nijs
Automatisatie van ASIC vericatie
Figuur 6.4:
7 8 9 10 11
ASICclient klasse
else if( securityType == argSSL ) { conn = new SSLclient(server, port, dbg); } else { //... }
12 13
aconn = new ASICclient( conn, dbg ); Codefragment 6.7:
Gebruik van de ASICclient klasse
De client kan nu (eventueel beveiligd) communiceren met een remote ASICserver object. Het is vereist dat zowel de client als de server hetzelfde type beveiliging (geen of SSL) gebruiken.
startup() De startup() functie zet een connectie op volgens het ASICproto protocol met de remote server. In een van de eerste versies probeerde de client tot driemaal te connecteren met de server wanneer het niet lukte. Momenteel probeert de client nog maar éénmaal: dit komt omdat het onderliggende TCP protocol ons eigenlijk garandeert dat het verzonden bericht aankomt. De netwerklaag daarboven garandeert ons dan weer dat het correct aantal tekens verzonden is (zie de API van de Networkfunctions::write() functie). We mogen dan veronderstellen dat de server daadwerkelijk het juiste bericht ontvangen heeft wanneer we het hem sturen. Krijgen we echter geen of een foutief antwoord van de server, dan wordt de verbinding onmiddellijk verbroken.
71
Karel Nijs
Automatisatie van ASIC vericatie
sendcmd() Deze functie giet het commando dat we van de Tcl GUI doorgegeven krijgen in een, voor het ASICproto, geschikte vorm. Het eectief versturen van een commando bestaat uit twee delen die we reeds besproken hebben: CMD en EXEC. Voor de buergrootte hebben we de standaardwaarde PIPE_BUF genomen. Deze waarde kan weliswaar verschillen op verschillende systemen, maar omdat het verschil in buergrootte en eectief gebruikte ruimte voldoende is om dit toe te laten, zal dit geen problemen opleveren. Je kan je afvragen of het niet eciënter geweest zou zijn, moesten we een vooraf gedenieerde buergrootte gebruiken. Het gebruik van enige buergrootte is immers altijd incorrect: zowel de client als de server moeten over dezelfde verzend/ontvangst buer beschikken om zeker al de verstuurde data te kunnen ontvangen. Is dit niet zo kan het zijn dat de server maar een half commando binnen ontvangt. Wanneer we dus een grootte vooropstellen naar gelang het grootst verwachte commando·, gaat deze altijd te groot zijn voor alle andere commando's én problemen kunnen opleveren wanneer er toch een langer commando zou voorkomen. Wanneer we trouwens de corresponderende read() en write() functies gebruiken, bewust zijnde van dit probleem, kunnen we ze wel eciënt gebruiken. Een voorbeeld: 1 2 3
int main (void) { char buffer[PIPE_BUF]; string testregel = "dit is een test regel";
4
sprintf( buffer, "%s", testregel.c_str() );
5 6
int res = write( 0, buffer, testregel.size() );
7 8
cout << "buffergrootte = " << PIPE_BUF << endl; cout << "tekstlengte = " << testregel.size() << endl; cout << "bytes geschreven = " << res << endl;
9 10 11 12
} Codefragment 6.8:
Eciënt gebruik van een PIPE_BUF grote buer
Wat er verder gebeurt na succesvol versturen, wordt door de Tcl C extensie bepaald (zie 6.8).
check_proces() Wanneer de GUI met een bepaald interval de server gaat contacteren voor het bestaan van een bepaald proces, wordt er van deze funtie gebruik gemaakt.
72
Karel Nijs
Automatisatie van ASIC vericatie
cancel() De cancel() functie was origineel geïmplementeerd op basis van de send_cmd() functie: we stuurden een kill commando met bijhorend PID naar de server. Een ongewenst gevolg hiervan is dat de client een commando kan sturen dat willekeurig proces beëindigd op de server (als hij er rechten voor heeft). Daarom hebben we ervoor gekozen een apart bericht te speciëren voor het annuleren van checks. 1 2 3
//eerste versie bericht 645421 @@@ CMD @@@ kill -s SIGTERM $PID && kill -9 $PID @@@ 6991 @@@ EXEC @@@
4 5 6
//hudige versie bericht 644441 @@@ CANCEL @@@ $PID Codefragment 6.9:
Annulatie bericht
get_server_info() Deze functie haalt de serverinformatie (uptime informatie) op van de server. De uitwisseling gebeurt met behulp van een INFO bericht.
6.5 Listener De Listener klasse is, zoals de naam het al verraadt, een klasse is een implementatie van een concurrent server.
luisteraar. Meer speciek: de Listener
Voor de basis van en meer uitleg over een concurrent server verwijzen we naar (10).
6.5.1 Aanmaken luisteraar Na het standaard aanmaken van een Debug object, wordt in het serverprogramma de luisteraar gecreëerd. De referentie (pointer) naar deze luisteraar wordt opgeslagen in een globale variabele van de AsicServer namespace: AsicServer::lst . We hebben voor deze afwijkende benadering gekozen omdat we vanuit de ASICserver klasse(n) aan het Listener object moeten kunnen komen. Deze functionaliteit is nodig in de AsicServer::ctrl_c() functie: hier moeten we immers aan het luisteraarobject kunnen om deze te stoppen wanneer er het SIGTERM signaal ontvangen wordt in de console. Het is niet gelukt die op een andere, meer propere, manier op te lossen. Een globale variabele in een van de headers is niet mogelijk, globale variabelen in het main programma zijn nog niet bekend in de klassen. Aan de ASICserver wordt weliswaar het Listener object meegegeven, maar aan de signal handler
73
Karel Nijs
Automatisatie van ASIC vericatie
kunnen we enkel globale functie meegeven. We gaan dit probleem meerdere keren tegenkomen, onder andere bij het opvangen van voltooide kindprocessen, threads, . . .
6.5.2 Conguratie luisteraar De luisteraar wordt zowel voor plain text als SSL op dezelfde manier gecongureerd. Deze conguratie bestaat uit het maken van een vast aantal instellingen: socket opties, signal handlers, aanmaken, binden van en luisteren op een socket. Wanneer al deze instellingen gebeurd zijn, is de luisteraar oneindig lang aan het luisteren op een bepaalde poort. Ook al treden er ernstige fouten op, we zouden nooit uit deze oneindige lus mogen gaan omdat dit een totale onbereikbaarheid van de server tot gevolg heeft.
6.5.3 Concurrent server De luisteraar kan gelijktijdig verschillende clients en console-invoer detecteren met behulp van de select() functie. De verschillende events worden afgehandeld in aparte POSIX threads. Wanneer er invoer langs console is, wordt een thread opgestart die deze invoer valideert. De enige invoer die we momenteel toelaten is het karakter q om de server af te sluiten. Er zou eventueel ook een reset optie toegevoegd kunnen worden die de luisteraar terug in zijn initiële startfase brengt (bijvoorbeeld nodig bij eventueel vastlopen).
Figuur 6.5:
Uitvoermodel concurrent server
Wanneer een nieuwe client zich aanmeldt bij de luisteraar, staat de luister le descriptor hoog en keert select() terug. De luisteraar voert de accept() functie uit die de client accepteert en hem een eigen le descriptor toekent. Met behulp van deze le descriptor kunnen we met de client communiceren.
74
Karel Nijs
Automatisatie van ASIC vericatie
6.5.4 Bijhouden clients De luisteraar kan maar een beperkt aantal clients tegelijk bedienen, anders gaan we de server te zwaar belasten en kan er niet meer voldoende geheugen zijn om alle clients te verwerken. De select() functie is hier op voorzien en maakt gebruik van een backlog: deze variabele denieert het aantal clients dat maximaal in de wachtrij kunnen staan. Intern moeten we ook alle geconnecteerde clients en hun bijhorende ASICserver objecten gaan bijhouden. We hebben deze immers nodig wanneer de administrator beslist om de service af te sluiten: het Listener::stop_listening() algoritme loopt alle ASICservers af die in het geheugen zitten, sluit hun verbinding en verwijderd ze het uit het geheugen. Een ASICserver blijft niet het geheugen gedurende uitvoer van het gestuurde commando, maar is connectiegebonden. Ook wanneer er geen geldige connectie volgens het ASICproto kan opgezet worden of alle acties voltooid zijn, werden de ASICservers eerst onvoorwaardelijk afgesloten. Met onvoorwaardelijk wordt er bedoeld dat de socket connectie onmiddellijk gesloten wordt, zonder het versturen van de resterende data in de buer. 1 2 3 4 5
//normal method if( Networkfunctions::socket_exists(send_sd) ) { shutdown( send_sd, SHUT_RDWR ); close(send_sd); }
6 7 8
//close immediately close(send_sd); Codefragment 6.10:
Aggressief sluiten socket
Dit wordt mede mogelijk gemaakt door de socketoptie die we instellen in de Networkfunctions:: socket() functie: 1 2 3 4
//linger: close socket immediately WITHOUT sending unsend data struct linger linger; linger.l_onoff = 1; //non-zero: close blocks till timeout is expired linger.l_linger = 0; //seconds
5 6
setsockopt(sd, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger) ); Codefragment 6.11:
Instellen socket opties
Deze aggressieve methode hebben we moeten toepassen omdat er anders veel connecties open blijven staan wanneer het opzetten niet volledig gelukt is of wanneer er andere problemen optreden. Het heeft geen zin om de SO_LINGER optie in te stellen wanneer je toch van de shutdown() functie zou gebruik maken: deze hebben namelijk tegenstrijdige doelen. Met behulp van shutdown() zou eerst nog alle niet verstuurde informatie in de buer verstuurd worden, terwijl de SO_LINGER optie met linger op nul seconden gezet, de verbinding onmiddellijk sluit.
75
Karel Nijs
Automatisatie van ASIC vericatie
Wanneer we deze methode echter gaan gebruiken, gaat we de remote host in de war sturen. Een TCP verbinding moet namelijk full duplex gesloten worden: zowel beide kanten moeten op de hoogte zijn van de sluiting en deze moet bevestigd worden. Wanneer we de verbinding onvoorwaardelijk zouden sluiten, kunnen er nog pakketten onderweg zijn waarvan de verstuurder er op rekend dat ze bevestigd zullen worden (zie (15) en ook (11)). Wanneer we close() gebruiken, wordt de nog te verzenden data eerst verstuurd. De propere manier zal dus wat langer duren. Een betere implementatie: 1 2 3
int Networkfunctions::close_socket(int sd) { fcntl(sd, F_SETFL, O_NONBLOCK); shutdown(sd, SHUT_WR);
4
char tmp[100]; while(recv(sd,tmp,100,0) > 0) ;/* nothing */
5 6 7 8
int res = close(sd);
9 10
while( res == EINTR ) res = close(sd);
11 12 13
return res;
14 15
} Codefragment 6.12:
Correct afsluiten socket
Met fcntl() stellen we in dat de thread niet mag blokkeren bij het schrijven van de data. Vervolgens sluiten we de socket voor schrijven en lezen we alle data in die de andere zijde nog gestuurd heeft. Als laatste proberen we de socket te sluiten. Omdat het voor kan komen dat deze actie onderbroken wordt door een signaal met hogere prioriteit, controleren we de terugkeerwaarde en proberen we eventueel opnieuw te sluiten. Al deze ASICserver objecten worden dus op luisteraarniveau bijgehouden. Dit werd aanvankelijk geïmplementeerd met de std::set. Omdat Valgrind lekken regelmatig geheugenlekken aangaf in de std::set::iterator en ook geheugenfouten bij het vergelijkingsmechanisme optraden, hebben we in eerste instantie geprobeerd de vergelijker zelf te implementeren4 . Omdat dit ook niet de gewenste problemen oplostte, hebben we uiteindelijke gekozen om van de std::set af te stappen en de std::vector te gebruiken. De werking van de vector is gelijkaardig aan deze van een set, doch werkt een vector met een vast aantal plaatsen terwijl de set met een ongedenieerd aantal plaatsen werkt. 4
Zie http://www.sgi.com/tech/stl/set.html
76
Karel Nijs
Automatisatie van ASIC vericatie
Dit leidt echter tot een grote beperking van de functionaliteit van de luisteraar: met een set kunnen we in theorie een willekeurig groot aantal clients tegelijk verwerken, terwijl we met een vector op voorhand een vast aantal moeten opgeven. Een vector kan niet van grootte veranderen zonder dat je hem volledig moet overzetten. Wanneer er verschillende clients connecteren, kan er wel eens iets misgaan. Normaal zou de connectie dan onmiddellijk gesloten moeten worden (zie boven). In praktijk blijkt dit echter niet altijd waar te zijn: tijdens extreme testen blijven bestaan sommige objecten na mislukking (hier komen we later nog op terug). Stel dat we maximaal 50 clients toelaten. Onze vector heeft dan ook maar eectief 50 beschikbare plaatsen. Wanneer deze vol zouden zijn, is er geen plaats meer voor nieuw clients en kan de server als onbereikbaar beschouwd worden. Zouden we met de set gewerkt hebben, stond het eectief geconnecteerde clients op minder dan 505 , maar kunnen meer dan 50 clients passief in de set aanwezig zijn. We kunnen dus nog altijd clients ontvangen. Dit passief in het geheugen aanwezig zijn van ASICserver objecten is in beide gevallen een ongewenste situatie: we willen namelijk het geheugengebruik van onze applicatie tot een minimum herleiden zodat we andere applicaties niet hinderen. Deze voorwaarde en de vereiste dat er vrije vectorposities moeten zijn, heeft geleid tot het Listener::getFreePosition() algoritme. Dit algoritme zoekt de de eerste vrije positie in onze vector en geeft hiervan de index terug. Op deze index kan het ASICserver object vervolgens opgeslagen worden. Wanneer er geen positie gevonden wordt, laat de luisteraar aan de connecterende client weten dat hij volzet is en de verbinding wordt gesloten.
6.5.5 Afhandelen clients Bij het ontvangen van de client wordt er allereerst beslist (aan de hand van een opstartinstelling van de service) of we hem met de PlainConn of SSLconn klasse gaan behandelen (zie Codefragment 14). Vervolgens wordt voor de client een ASICserver object aangemaakt. Tot nu waren alle acties met betrekking op de communicatie immers op zeer elementair niveau: de ASICserver brengt de communicatie tot op het ASICproto niveau. Na het opslaan van het ASICserver object wordt de client verder behandeld in een aparte thread. In deze thread wordt de feitelijke communicatie opgestart. Aan de hand van ontvangen berichttypes worden de juiste functies opgeroepen van de ASICserver. We hebben hier gekozen om deze acties binnen de luisteraar uit te voeren. Wanneer we de luisteraar zouden afsluiten, moeten immers ook alle ASICservers en hun bijhorende communicatie(kanalen) stopgezet worden. 5
Dit aantal werd telkens aangepast bij het beëindigen/mislukken van een connectie
77
Karel Nijs
Automatisatie van ASIC vericatie
6.5.6 Opkuisen clients Wanneer de ASICserver klaar is met de behandeling van zijn client, wordt de verbinding afgesloten en keert de thread terug. Omdat we met objecten en pointers gewerkt hebben, blijft het object echter nog bestaan in het geheugen (C++ heeft geen automatische garbage collection ). Daarom voeren we, na het aannemen van elke client, de Listener::clean_sockets() functie uit: deze functie gaat alle objecten af en controleert of de connectie nog actief is. Wanneer de connectie niet actief is, wordt het ASICserver object uit het geheugen verwijderd en de positie in de vector vrijgegeven. Als je goed hebt kunnen volgen tijdens de uitleg, heb je waarschijnlijk gemerkt dat de vector twéémaal overlopen wordt per connecterende client. Bij Listener::getFreePosition() kan het doorlopen weliswaar voortijdig onderbroken worden, maar het zou toch beter zijn moesten we dit in één keer kunnen doen. De Listener::getFreePosition() is dan ook gelijkaardig aan de Listener::clean_sockets() functie. We krijgen nu volgende implementatie: 1 2
3 4 5 6 7 8
/** * get the first free position in the connections vector and clean out finished connections * @param connections the connections vector * @return the first free position in the connections vector */ int Listener::getFreePosition(vector &connections) { int ret(-1); int j(0);
9 10 11 12 13
pthread_mutex_lock(&mutex); while( ret==-1 && j<(int)connections.size() ) { ASICserver* serv = (ASICserver*) connections[j];
14 15 16
if( serv != NULL ) { int sd = serv->get_socket();
17 18 19 20 21 22 23 24 25 26 27
if( !Networkfunctions::socket_exists(sd) ) { serv->close_conn(); } if( serv->isFinished() ) { delete connections[j]; connections[j] = NULL; ret = j; } } else ret = j;
78
Karel Nijs
Automatisatie van ASIC vericatie
28
j++; } pthread_mutex_unlock(&mutex);
29 30 31 32
return ret;
33 34
} Codefragment 6.13:
Listener::getFreePosition()
Er wordt hier ook gewerkt met pthread mutexen. Deze methode is nodig om het gebruik van een gedeelde variabele (hier Listener::connections) in goede banen te leiden. In de Listener::connections variabele zitten namelijk (referenties naar) ASICserver objecten. Wanneer in thread A een object verwijderd en gelijktijdig in thread B aangesproken zou worden, wordt er een geheugenfout (Segmentation Fault) gegenereert. Een geheugenfout heeft een onmiddellijke beëindiging van het huidige programma tot gevolg. Een hoogst ongewenste reactie als je wilt dat je service 24 op 24, 7 op 7 beschikbaar is. De conguratie van de threads wordt dan: 1
#define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
2 3 4 5 6 7 8
//set thread attributes pthread_attr_t attr; pthread_attr_init( &attr ); pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED ); pthread_attr_setstacksize ( &attr, THREAD_STACK_SIZE ); pthread_mutex_init( &mutex, pthread_mutexattr_default ); Codefragment 6.14:
Conguratie van thread mutexen
Wanneer er een client connecteert, krijgen we volgende situatie: 1 2 3 4 5 6
//make connection objects IConnection *sconn; if( useSSL) sconn = new SSLserver(recv_sd, client, dbg); else sconn = new PlainServer(recv_sd, client, dbg);
7 8 9 10
pthread_mutex_lock(&mutex); connections[pos] = new ASICserver(sconn, dbg, this);
11 12 13 14 15 16
//fill in arguments for the thread Client_arg args; args.aconn = connections[pos]; args.dbg = dbg; pthread_mutex_unlock(&mutex);
79
Karel Nijs
Automatisatie van ASIC vericatie
17 18 19 20 21
//thread creation res = pthread_create( &id, &attr, &process_client, (void*) &args ); if( res == EAGAIN) dbg->write( "Not enough system resources to create new thread", __FUNCTION__, 2 ); Codefragment 6.15:
Ontvangen van clients en thread mutexen
We gebruiker hier detached threads omdat we niet moeten wachten op het einde van de thread. Wanneer een thread eindigt, geeft hij in het laatste statement zijn bronnen vrij (met pthread_exit( (void*)NULL )). Het resultaat wordt hier niet teruggegeven omdat we dit niet nodig hebben en omdatwe ook niet op het einde van de thread wachten:
6.6 ASICserver
Figuur 6.6:
ASICserver object model
De ASICserver klasse implementeert aan serverzijde de afhandeling van het protocol.
6.6.1 startup() Tijdens het opstarten wordt een random seed gegenereerd en een PSgen object aangemaakt. De seed wordt tijdens de HELLO sequence naar de client verstuurd.
6.6.2 recv_msg() Deze functie zit er nog in om historische redenen: aanvankelijk werd het eerste bericht met omgekeerde veldvolgorde gestuurd omdat er nog geen sequentienummer is. Omdat deze actie
80
Karel Nijs
Automatisatie van ASIC vericatie
gebeurt in de Listener klasse, hebben we geen toegang tot de ASIChost::readMsg() functie. De herimplementatie van de process_client() functie staat op het ToDo-lijstje van de API.
6.6.3 exec_cmd() Tijdens de uitleg van de exec_cmd() functie gaan we je proberen mee te nemen met onze gedachtengang: bij een eerste versie van de ASICserver werd het uitvoeren van een commando nog als een zeer eenvoudig probleem beschouwd. Wanneer we echter volledige controle willen krijgen over het proces komt er meer bij kijken. . .
Aanmaak nieuw proces Wanneer het commando ontvangen en goedgekeurd is, gaan we het proces forken en in het aangemaakte kind proces het commando uitvoeren met system(). In de ouder wordt de PID van dit kind bijgehouden in een std::set (hiervoor gebruiken we weer de AsicServer::lst (namespace) globale variabele (zie 6.5.1)). Het kind handelt de client zelf verder af. Omdat fork() het proces kopieert, zijn er trouwens twee ASICservers die vanuit dezelfde sockets invoer lezen of er naartoe schrijven (zie (10, Hoofdstuk 13)). Dit is geen ideale situatie. Een tweede oplossing bestaat eruit om het afhandelen van de client niet door het kind, maar door de ouder te laten doen. Wanneer een kindproces dan eindigt, verwijdert de ouder het kind PID uit de set in de juiste adresruimte. We moeten nu echter weten wanneer het kindproces beëindigd is. Hiervoor hadden we eerst een sigaction() geïmplementeerd die SIGCHLD signalen opvangt. Maar op deze manier wordt er ook een SIGCHLD signaal opgevangen wanneer een client disconnecteert en het (gekopieerde) ASICserver object zichzelf beëindigd (nog altijd een gevolg van het gekopieerde proces met behulp van fork()). Een tweede probleem hiermee: je kan niet de (pointers naar) objecten gebruiken uit het ouderproces, want de pointers worden relatief in de adresruimte van het programma genomen. Wanneer we dan een functie, nanny(), zouden schrijven die terugkerende kindprocessen opvangt, kunnen we niets doen met deze informatie omdat we niet aan de gegevens in het hoofdprogramma komen (tenzij een ineciënte en ingewikkelde oplossing met behulp van globale variabelen)6 . Wanneer we echter een pipe aanmaken alvorens fork() aan te roepen, kunnen we aan interprocess communication doen. De ouder voegt zoals eerder vermeld het kind PID toe aan de set in zijn adresruimte. Hierna maakt hij een thread aan die leest van de aangemaakt pipe en blijft blokkeren. Het kind gaat nu echter, na terugkeren van het system() commando, zijn eigen PID naar de pipe schrijven. 6
De
nanny()
functie kan niet aan de programmavariabelen omdat dit een statische functie is waaraan
parameters doorgegeven kunnen worden
81
geen
Karel Nijs
Automatisatie van ASIC vericatie
Wanneer de thread, door de ouder opgestart, van de pipe kan lezen (we laten hem blokkeren), weet hij dat het kindproces beëindigd is. Vervolgens verwijdert hij de PID uit zijn set van PID's. Dit lijkt een werkende oplossing, maar we vergeten echter dat we met fork() nog altijd een kopie genomen hebben van het oorspronkelijke proces. We hebben dus nog altijd een werkende luisteraar en ASICserver klasse, die beide in- of uitvoer verwachten. Met behulp van de vfork() functie kunnen we de geheugenruimte delen tussen de processen, zodat we niet alle dubbele descriptors moeten afsluiten. De methode om deze hele situatie correct op te lossen, is door gebruikt te maken van de POSIX exec() functies. Wanneer we gebruik maken van exec() in plaats van system() overschrijven we de huidige adresruimte van de proceskopie, doch behouden we de PID. Een vergelijking van de functies waarmee we het commando gaan uitvoeren:
system(commando) Voert het commando uit en blijft blokkeren tot het voltooien hiervan. Dit commando heeft dezelfde read() en write().
werking op besturingssystemniveau als standaard functies zoals
execl(prog, arg0, . . . , argx, NULL) Voert het programma prog uit en geeft de argumenten arg0 tot en met argx mee. execl() overschrijft het huidige proces en keert niet terug.
Bijvoorbeeld: 1
string cmd = "source /path/to/src && calibre -hier /path/to/rules >log 2>errorlog ";
2 3 4
system( cmd.c_str() ); execl( "/bin/bash", "bash", "-c", cmd.c_str(), NULL );
Executioner Wanneer we echter execl() op deze manier gaan gebruiken, wordt er nog een proces aangemaakt: we voeren immers /bin/bash -c uit en deze maakt weer een apart proces aan. Wanneer we dan de check zouden willen annuleren (door CANCEL + pid te sturen), wordt enkel ons aangemaakt kindproces afgesloten en niet het proces gestart door /bin/bash! Ook kunnen we ons pijpsysteem niet meer gebruiken: omdat execl() niet terugkeert, zal de PID in het kind nooit naar de pipe geschreven kunnen worden omdat we er gewoonweg niet geraken7 . Daarom hebbe we gebruik gemaakt van een apart programma executioner dat twee argumenten aanneemt: als eerste de pipe socket descriptor, als tweede het commando. In dit apart programma gaan we de system() code die we in de vorige methode gebruikt hebben, plaatsen. 7
Tenzij bij een fout van
execl().
82
Karel Nijs
Automatisatie van ASIC vericatie
Het commando wordt nu (weer) uitgevoerd met behulp van system(). Na voltooien wordt de PID naar de pipe geschreven en wordt deze pipe gesloten. We mogen echter niet vergeten dat system() zelf óók weer een Bash shell opstart. Wanneer we het kindPID zouden killen, zou dit commando blijven voortleven. Toegepast op onze situatie: 1. De client maakt connectie met de server en stuurt zijn command cmd door. 2. Het ASICserver object maakt een pipe aan, maakt een kopie van zichzelf met behulp van fork() en overschrijft deze kopie (kindproces) met execl(). 3. Het executioner programma start de uitvoer van system(cmd). Er bestaan nu volgende processen op de server: 1 2
3 4
$ ps aux | grep calibre | grep -v grep karel 11784 0.0 0.3 2424 836 pts/1 calibre karel 11785 0.0 0.4 2280 1004 pts/1 karel 11786 0.0 0.4 2284 1048 pts/1 bin/calibre
S+
19:21
0:00 executioner 7
S+ S+
19:21 19:21
0:00 sh -c calibre 0:00 /bin/bash /usr/
Wanneer we het eerste proces 11784, opgestart met execl(), zouden killen, blijven de twee onderste processen, 11785 en 11786, verder bestaan. Pas wanneer je 11786 killt, zijn alle processen beëindigd. Om deze drempel te overstijgen, hebben we gebruik gemaakt van de setpgid() functie. setpgid() laat je toe om aan jobcontrole te doen door de processen te groeperen. Wanneer we deze functie aanroepen in zowel het kindproces van de ASICserver, als in het executioner programma, kunnen alle nodige processen in één keer stoppen8 . Je kan nu de 1 2 3 4
process group id (PGID) zien in de derde kolom9 :
$ ps -ef | grep calibre | grep -v grep karel 13433 13179 0 20:56 pts/1 00:00:00 executioner 13433 11 calibre karel 13434 13433 0 20:56 pts/1 00:00:00 sh -c calibre_traag karel 13436 13434 0 20:56 pts/1 00:00:00 /bin/bash /usr/bin/calibre
Uitvoeren commando in code Wanneer we deze sectie samenvatten in pseudocode krijgen we: 1 2
8 9
#ifdef IMEC #define EXECUTIONER "/imec/other/guiasic/eindwerk_CVS/eindwerk/netwerklaag/ netwerklaag/src/executioner"
Hiervoor moet je
kill()
wel oproepen met een - voor de PID
Merk de PID (niet PGID) op die deel uit maakt van de
83
executioner
opdracht.
Karel Nijs
3 4
Automatisatie van ASIC vericatie
#endif //...
5 6
sigaction( SIGCHLD, nanny, NULL ); //process catcher
7 8 9
int fd[2]; res = pipe( fd );
10 11
pid = (int) vfork();
12 13 14 15
if( pid == 0 ) { //in CHILD process //close reading side of pipe close( fd[0] );
16
pid = (int) getpid(); res = setpgid( 0, pid );
17 18 19
int res = execl( EXECUTIONER, EXECUTIONER, pid, fd[1], cmd, NULL );
20 21
//if we get here execl() failed => write negative PID to pipe gvd.str(); gvd << ( pid * (-1) ); res = write( fd[1], gvd.str().c_str(), gvd.str().size() );); close( fd[1] );
22 23 24 25 26 27
//exit in case of execl() failure //@danger using "exit()" in stead of "_exit()" will lead to Segmenation Faults _exit(EXIT_FAILURE);
28 29 30 31 32 33 34 35
} else { //in PARENT process //close writing side of pipe close( fd[1] ); listener->add_pid( pid );
36
pthread_create(&id, NULL, &pipe_reader, (void*) &args);
37 38
close( fd[0] );
39 40
//generate PID message for the client msg = generateMessage(gen, PID, out.str()); conn->sendmsg(msg);
41 42 43 44
return 0;
45 46
} Codefragment 6.16:
ASICserver: Uitvoeren commando's in pseudocode
84
Karel Nijs
Automatisatie van ASIC vericatie
Wanneer het execl() statement mislukt, wordt de schrijfzijde van de pijp afgesloten en de PID toegevoegd aan de set met slechte PID's van de luisteraar. Het kind wordt afgesloten met de _exit() functie (merk de underscore op). Aanvankelijk werd dit op de propere manier (met exit()) gedaan, maar we kregen dan regelmatig geheugenfouten op dit punt.
Excutioner in code Het executioner programma: 1 2 3
//set process group int pid = atoi( argv[1] ); setpgid( 0, pid );
4 5 6
//get pipe socketdescriptor int fd = atoi( argv[2] );
7 8 9 10
//execute command int factor(1); res = system( argv[3] );
11 12 13
if( res == -1 || WEXITSTATUS(res) == 127 ) factor = -1;
14 15 16 17
//"catch" permission denied error if( WEXITSTATUS(res) == 1 ) factor = -1;
18 19 20 21
//command execution completed! out.str(); out << (factor * (int)getpid());
22 23
write( fd, out.str().c_str(), out.str().size() );
24 25 26
//close pipe close( fd );
27 28 29
//exit with success exit(EXIT_SUCCESS); Codefragment 6.17:
Executioner: Uitvoeren commando in pseudocode
Ik wil even opmerken dat we in plaats van de executie met executioner ook thread IDs hadden kunnen bijhouden:
• een thread ID is namelijk ook uniek;
85
Karel Nijs
Automatisatie van ASIC vericatie
• threads eindigen ook wanneer het hoofdprogramma eindigt (indien de threads zo gecongureerd zijn tenminste); • je kan geheugen delen met het hoofdprogramma; • threads kunnen eenvoudig aangemaakt worden in vergelijking met het fork-exec principe. Een belangrijk en doorslaggevend nadeel van threads is dat je ze niet ziet wanneer je de process table opvraagt: ze gaan namelijk verborgen zijn en enkel het proces dat hun gecreëerd heeft, is zichtbaar. Wanneer de eindgebruiker dan een server uitkiest op welke hij de check(s) wilt uitvoeren, kan hij onbewust een server kiezen die eigenlijk al zwaar belast is (hij kan immers niet waarnemen dat de check in uitvoering is). Wanneer je de pseudocode van executioner aandachtig bekijkt, zie je dat de terugkeerwaarde van system() gecontroleerd wordt. Op deze manier kunnen we de Bash syntax fouten opvangen (zie Codefragment 9). Wanneer er namelijk een fout optreedt, gaan we de PID negatief op de pijplijn zetten. De luisteraar gaat dit opmerken en de PID uit zijn set met actieve PID's halen en in de set van slechte PID's steken. De volgende keer dat de client een aanvraag stuurt voor het bestaan van die bepaalde PID, gaat de ASICserver een NACK bericht sturen met negatieve PID. De client merkt dit op en geeft de Failed status door naar de GUI. Deze oplossing laat een betere opvolging toe: wanneer de gebruiker nu een fout krijgt, weet hij beter waar het (mogelijk) aan zou kunnen liggen.
Besluit Ondertussen hebben we al onze doelstellingen bereikt: 1. Eciënt geheugenbeheer door de lokale variabelen
niet mee te kopiëren.
2. We hebben geen meerdere luisteraars of ASICservers meer die naar dezelfde client(s) luisteren omdat het proces nu overschreven wordt met behulp van execl(). 3. We weten wanneer een kindproces voltooid is omdat we de PID op de pipe zetten en een (blokkerende) thread hebben die hier van leest. 4. Wanneer de Bash processubstitutie mislukt, kunnen we dit aan de gebruiker melden. 5. We hebben een PID als handle voor het executioner programma en kunnen hiermee de commando executie stoppen. 6. Alle processen die verder aangemaakt worden, worden mee beëindigd tijdens het stoppen van het kindproces omwille van setpgid().
86
Karel Nijs
Automatisatie van ASIC vericatie
7. Kindprocessen die eindigen worden opgevangen in onze nanny() functie zodat er zeker geen zombieprocessen kunnen bestaan. Je kan het natuurlijk ook op een heel andere manier implementeren: gewoon het kindproces laten uitvoeren en periodiek met kill -0 pid controleren of het al voltooid is. Vervolgens de PID uit de set verwijderen (enkel mogelijk wanneer onze periodiek controlerende functie toegang heeft tot de adresruimte van het hoofdprogramma) en dit melden aan de client wanneer hij de volgende keer connecteert.
6.6.4 kill_process() Deze functie zorgt voor het beëindigen van een bepaald proces waarvan de client ons de PID stuurt. Een proces kan enkel beëindigd worden als het in de set van de goede PID's zit. Een proces sluiten we af met het SIGTERM signaal. Op deze manier kunnen eventueel gebruikte systeembronnen en geopende les proper afgesloten worden door het proces. Zoals in de vorige sectie vermeld, geven we een negatief PID door aan het kill commando zodat de hele procesgroep ineens afgesloten wordt. Na afsluiten wordt de PID uit de set van 1 2
goede PID's verwijderd.
if( listener->pid_exists(pid) ) { res = kill( (pid*-1), signal );
3 4 5 6
if( res > -1 ) { msgcode = ACK; listener->remove_pid( pid );
7 8 9 10 11 12 13
out << "Killed process " << pid << " and removed it from execution queue."; } } else { msgcode = NACK; out << "Tried to kill non-existing process " << pid; }
14 15 16
msg = generateMessage(gen, msgcode, out.str()); conn->sendmsg(msg); Codefragment 6.18:
De kill_proces() functie
6.6.5 server_info() Het opvragen van de serverinformatie wordt ook met C++ geïmplementeerd en is platformafhankelijk.
87
Karel Nijs
Automatisatie van ASIC vericatie
Een eerste versie liet een Bash script de server informatie opvragen; de uitvoer werd naar een tijdelijk bestand omgeleid. De huidige aanpak maakt op het GNU/Linux platform gebruik van het /proc/loadavg bestand. Uit deze le haalt ook het uptime commando zijn informatie. We hebben zo wel geen informatie beschikbaar over het aantal ingelogde gebruikers op de server, maar deze informatie kan je ook bekomen door gebruik te maken van de Monitor functie in de Tcl/Tk GUI.
6.6.6 send_pid_exists() De implementatie van deze functie is haast triviaal: de client vraagt om het bestaan van een bepaald PID te bevestigen. Bestaat dit proces wél op de server (het zit in de goede set PID's), dan wordt er een ACK bericht gestuurd. In het andere geval wordt er een NACK bericht gestuurd. Zit dit proces echter in de slechte set PID's, dan sturen we zoals reeds beschreven een NACK bericht, maar dan met een negatief PID.
6.7 Server De server service is de implementatie van een samenwerking tussen de Listener en ASICserver klassen. De server service is (natuurlijk) een apart programma dat gestart moet worden bij opstarten van de server en in principe nooit mag eindigen (anders zouden de clients immers niet kunnen connecteren). In tegenstelling tot aan de clientzijde hebben we hier dus met twee aparte klassen moeten werken. Hier spreek je echter niet van een extra laag, maar een proces dat parallel met het hoofdproces uitgevoerd wordt. Net zoals bij de Tcl GUI kan je parameters meegeven bij het opstarten van de service:
• de poort10 waarop de server luistert, • het type beveiliging, • de debug modus, Ook voor de server service is een man page ontwikkeld.
6.7.1 Opstarten server service Willen we 100 percent beschikbaarheid van de service, dan wordt deze best toegevoegd aan het default run level van de server. 10
Onder de 1024 heb je administratorpermissies nodig
88
Karel Nijs
Automatisatie van ASIC vericatie
6.8 Samenwerking met de GUI 6.8.1 Tcl C extensie De samenwerking tussen de GUI en de netwerklaag (enkel aan clientzijde natuurlijk) wordt geïmplementeerd met een Tcl C extensie. Tcl voorziet de mogelijkheid om zelf uitbreidingen te schrijven (in C of C++) zodat er nieuwe commando's beschikbaar zijn in de GUI. Wij hebben om de commando's door te geven naar de netwerklaag het ::nw_service::my_socket commando gedenieerd.
Het ::nw_service::my_socket commando Ons commando aanvaard zes of meer parameters, zie Tabel 6.1. Een meer uitvoerige beschrijving: 1. Het paswoord wordt in de GUI gegeneert door een geheim algoritme en vervolgens doorgegeven naar my_socket. Hier wordt het opnieuw gegeneerd en vergeleken. 2. Het beveiligingstype kan plain of ssl zijn. 3. Boolean waarde of de socket in stille modus opgestart met worden. Standaard neem je best de stille modus, anders krijgt de eindgebruiker veel onrelevante informatie te zien in de console. 4. De opdracht duidt het type actie aan dat we willen uitvoeren. Mogelijke waarden zijn: sendCMD, exist, cancel en information 5. Specicatie van de remote host waarmee connectie gemaakt moet worden. 6. Het eerste commando dat uitgevoerd moet worden. Momenteel wordt enkel deze optie gebruikt omdat de buers groot en de commando's kort genoeg zijn om alles in één keer te versturen. Positie 1 2 3 4 5 6 7
Beschrijving paswoord beveiligingtype debug type de opdracht de server en poort het eerste uit te voeren commando andere uit te voeren commando's Tabel 6.1:
Positionering commando's in ::nw_service::my_socket commando
89
Karel Nijs
Automatisatie van ASIC vericatie
7. Voorlopig niet gebruikt. Een voorbeeldaanroep kan er zo uit zien: 1
::nwservice::my_socket [genPass] ssl 1 sendCMD tarzan:5001 " bash -c ... "] Codefragment 6.19:
Tcl aanroep van ::nw_service::my_socket
Merk op dat er als paswoord enkel de functie naam, genPass(), vermeld is in het commando. De genPass() functie neemt geen argumenten aan en de uitvoer ervan is niet zichtbaar in console wanneer het my_socket commando zou mislukken.
Werking De Tcl C extensie is voor de client de uitvoerende klasse, net zoals de Listener klasse dit voor de server is. De globale werking (geïmplementeerd door my_socketCmd()): 1. De GUI roept het commando aan met het juist aantal parameters. 2. We zetten de parameters om in het gewenst formaat (herhaling: Tcl heeft geen types) en valideren het paswoord. Voldoet het paswoord niet aan de eisen, dan genereren we een fout. 3. Hierna controleren we of de opgegeven opdracht wel een opdracht is die we kennen, zoniet, geven we een foutmelding. 4. Vervolgens maken we een ASICclient object aan die de connectie met de server opstart. 5. Wanneer de connectie geslaagd is, voeren we onze
actie uit.
6. Met behulp van de terugkeerwaarde van onze actie stellen we een bericht samen dat doorgegeven wordt aan de GUI. Dit bericht is een standaard string en heeft geen speciale vereisten. 7. Als laatste verbreken we de connectie met de server.
6.8.2 Berichten doorgeven Zoals net besproken wordt de gewonnen informatie in stringvorm doorgegeven aan de GUI. De GUI beslist zelf wat er met deze informatie gebeurt (tonen in tekstveld, statusbalk, foutgeneratie, . . . ).
6.8.3 Foutmeldingen De hele bedoeling van de netwerklaag was om het hele gebeuren meer in de hand te hebben. Nu we met de server service de uitvoer volledig (kunnen) besturen, is het ook de bedoeling aan de clientzijde zo goed mogelijk het resultaat hiervan terug te geven. Een onderdeel daarvan zijn de
90
Karel Nijs
Automatisatie van ASIC vericatie
foutmeldingen. We hebben eerder vermeld dat het opvangen van alle mogelijke fouten met een groot geconstrueerd command in Tcl geen sinecure is. Nu we op het laagst mogelijke niveau zitten, hebben we dit echter volledig in handen. Wanneer een bepaalde actie fout gaat, kunnen we de GUI onmiddellijk melden waar het probleem zich precies voorgedaan heeft: verkeerd netwerkadres, server oine, foutief commando, gefaald proces, enz. We maken hier dan ook gretig gebruik van in de implementatie van my_socket. 1 2 3 4
# gebruikt commando: # ::nwservice::my_socket [genPass] ssl 1 exist tarzan:5001 46663] try { //...
5 6 7 8 9
if ( .. ) { //... } else if(cmd == (string)argEXIST) { aconn = get_ASICclient( remote, interp, sslOrPlain, &dbg );
10 11 12
int pid = Networkfunctions::Atoi( arg.c_str(), &dbg, 2 ); string restMsg = "";
13 14 15
res = aconn->check_process(pid, &restMsg); res = ( res == atoi(ACK) ) ? 0 : -1;
16 17 18 19 20
//NACK received? if( res == -1 ) { int rpid = Networkfunctions::Atoi( restMsg.c_str(), &dbg, 2 );
21
if( rpid == pid*(-1) ) { out.str(""); out << "\nProcess " << pid << " exited with an error on the server.\n"; out << "\nPossible errors:\n"; out << "\t* you don't have read/write permissions in the working directory \n"; out << "\t* the given command is wrong (syntax error, unknown command, file not found, ...) -> check Tcl code\n"; out << "\t* the executioner is not working -> check C++ code\n"; out << "\t* the bash shell is not found -> check system\n"; throw ASICexception( out.str() ); }
22 23 24 25 26
27
28 29 30 31 32
}
33 34
//normal exit
91
Karel Nijs
Automatisatie van ASIC vericatie
Tcl_Obj* tclres = Tcl_NewIntObj(res); Tcl_SetObjResult(interp, tclres);
35 36 37 38 39 40 41 42 43
} else { //... } } catch(ASICexception &ex) { string msg = ex.getMessage(); Tcl_AddErrorInfo( interp, (char*)msg.c_str() );
44 45 46 47 48
ret = TCL_ERROR; } catch(...) { out.str(""); out << __FUNCTION__ << ": Unknown execption" << endl;
49
Tcl_AddErrorInfo( interp, (char*)out.str().c_str() );
50 51
ret = TCL_ERROR;
52 53
} Codefragment 6.20:
Foutopvanging en foutberichtgeneratie
6.8.4 Opstarten GUI De hele applicatie wordt bij IMEC onder de guiasic project account geïnstalleerd. Iedereen van de eindgebruikers moet echter de juiste permissies hebben om de GUI uit te mogen voeren. Wanneer we de projectaccount toegankelijk maken voor de leden van de afdelingen, dan impliceert dit dat ze ook toegang hebben tot de volledige Tcl broncode (deze is namelijk leesbaar omdat Tcl een scripttaal is) en tot de geheime mappen. De beveiliging van de applicatie steunt echter op geheimhouding van bepaalde algoritmes en certicaten. De eindgebruiker mag in geen geval misbruik kunnen maken van deze situatie. We geven dus voor de project account best alleen maar permissies aan de eigenaar en de groep (Herhalaling: de guiasic account zit in zijn eigen guiasic groep). De gebruikers die toegang willen hebben tot de GUI geven we uitvoerrechten op de executionable die de GUI opstart. Omdat de Tcl script les (en de mappen waarin ze zitten) echter gelezen moeten kunnen worden om ook uitgevoerd te kunnen worden, hebben de eindgebruikers nog altijd niet genoeg rechten om de applicatie op te starten. Dit probleem hebben we opgelost door het runasicgui programma. Een beschrijving van alle commando's om de permissies in te stellen, vind je terug in Appendix C.
92
Karel Nijs
Automatisatie van ASIC vericatie
Het runasicgui programma Dit programma maakt het mogelijk om een programma uit te voeren, met de SUID gezet. Wanneer we de SUID zouden zetten op een script en dit script daarna een ander programma uitvoert (in ons geval Tixwish), kunnen we niet meer van de functionaliteit van SUID gebruik maken. Wanneer het programma waarop de SUID bit gezet is echter een gecompileerd programma is, wordt dit als één geheel beschouwd. Onderstaande code toont de implementatie vanrunasicgui: 1 2
3
#ifdef IMEC #define PROG "/imec/other/guiasic/eindwerk_CVS/eindwerk/eindwerk/scripts/ verification.sh" #endif
4 5 6
int main(int argc, char* argv[]) { string cmd_line( PROG );
7
//start at 1, otherwise the "rungui" will be included with the parameters for(int i=1 ; i<argc ; i++) { cmd_line.append(" "); cmd_line.append(argv[i]); }
8 9 10 11 12 13
uid_t euid = geteuid(); setreuid( euid, euid ); system( cmd_line.c_str() );
14 15 16 17
printf("\n");
18 19
fflush(stdout);
20 21
} Codefragment 6.21:
Het runasicgui programma
Met geteuid() vragen we de eectieve user ID (UID) op. Dit is de UID waarmee het huidige programma eectief aan het werken is, in ons geval de guiasic gebruiker, omwille van de SUID bit. Met setruid() zetten we de echte UID van het proces zodat we Tixwish kunnen uitvoeren als de guiasic gebruiker. Dit heeft echter wel een groot nadeel: nu de gebruiker terug meer rechten heeft, kan hij via onze GUI naar de verboden bestanden browsen en deze zelfs openen of bewerken! Om dit op te vangen, moeten we het browsegedrag van de gebruiker controleren en toegang weigeren waar nodig.
93
Karel Nijs
Automatisatie van ASIC vericatie
Dit hebben we in de Tcl programmalogica geïmplementeerd. Hier controleren we na de keuze van een directory of deze niet vermeld is een lijst met verboden mappen.
94
Hoofdstuk 7
SSL implementatie We hebben in het vorige hoofdstuk de werking van zowel de client, de server als de Tcl C extensie uitgebreid bekeken. We hebben echter nog niets vermeld over de implementatie van de SSL sockets. De implementatie hiervan is een lastig en langdurend karwei geweest: er is online weinig documentatie te vinden (de OpenSSL documentatie zelf is nog altijd in aanmaak) en de laatste uitgegeven boek is al enkele jaren oud. Tijdens het uitpluizen van de documentatie hebben we dan ook veel gebruik gemaakt van nieuwsgroepen (onder andere mailing.openssl.users) en online beschikbare code (vaak gevonden via publiek toegankelijke CVS, te vinden met Google).
7.1 SSL Algemeen Wanneer je een met SSL beveiligde verbinding wilt opzetten tussen twee hosts, moeten er afspraken gemaakt worden. Deze afspraken handelen over de gebruikte encryptie, MAC, (wederzijdse) validatie, geldigheidsduur, . . . Afspraken worden gemaakt tijdens het SSL handshake protocol. Een client kan meerdere connecties met een bepaalde server maken, daarom is het handig wanneer hij niet telkens opnieuw over de connectieparameters moet onderhalen. Met behulp van SSL sessies kan je meerdere connecties per sessie maken en moet er maar éénmaal onderhandeld worden. Omdat het onderhandelen, zeker wanneer je Die-Hellmann gebruikt, langer duurt dan het opzetten van een standaard socketverbinding, kan het gebruik van sessies wat tijd uitsparen. Voor een grondige uitleg verwijzen we naar (5, Slides SSL) en (7, Chapter 1). Enkele garanties van SSL:
• client en server authentisering met behulp van certicaten en sleutels,
95
Karel Nijs
Automatisatie van ASIC vericatie
• geheimhouding door encryptie van de gestuurde boodschappen, • integriteit van gestuurd bericht met behulp van MAC.
7.1.1 SSL of TLS Om te programmeren met secure sockets zijn er verschillende SSL versies beschikbaar: SSLv2, SSLv3 en TLSv11 . Deze versies kunnen niet met elkaar werken: tijdens het onderhandelen moet er één gekozen worden. Belangrijkste verschillen tussen SSLv2 en SSLv3 (in 13, Chapter 21):
• SSLv2 ondersteunt geen client authenticatie, • SSLv2 is gevoelig voor de
man-in-the-middle attack,
• SSLv3 heeft meer ciphers, • SSLv3 is ontworpen door een cryptograaf, terwijl SSLv2 ontworpen is door een programmeur. Belangrijkste verschillen tussen SSLv3 en TLSv1 (in 2, Chapter 3):
• TLSv1 is geïmplementeerd door de IETF groep, • TLSv1 is meer beveiligd op gebied van cryptograsche sleutels en MAC constructie, • TLSv1 ondersteunt Die-Hellman sleutelafspraken, de Digital Signature Standard en TripleDES encryptie. Hierbij willen we opmerken dan zowel SSLv3 als TLSv1 backward compatible zijn: wanneer ze connecteren met een andere host die het recenste protocol niet ondersteunt, zal er protocol gekozen worden die door beide ondersteund wordt. TLSv1 wordt zelfs beschouwd als SSLv3.1 en meestal worden beide ondersteund. Ik heb ervoor gekozen om TLSv1 te implementeren, vooral omdat het de veiligste van de drie is en het door de IETF aangenomen is (wat we dan als standaard mogen beschouwen). Verder kunnen we nog altijd overschakelen naar SSLv3 wanneer nodig. We gaan niet toelaten de communicatie te voeren volgens het SSLv2 protocol, aangezien dit een groot nadeel zou zijn voor de beveiliging. 1
SSLv1 is nooit publiek beschikbaar gemaakt.
96
Karel Nijs
Automatisatie van ASIC vericatie
7.1.2 SSL API Om een applicatie te kunnen ontwikkelen, heb je een API nodig. Momenteel zijn er verschillende API's beschikbaar om SSL te implementeren: OpenSSL, SSLeay2 , NSS SSL/TLS API, Cryptlib, ... Bij de keuze van de API moeten we rekening houden met:
• de licentie: liefst Open Source en
gratis,
• de beschikbaarheid op de servers bij IMEC, • de beschikbare informatie. Met deze drie dingen in het achterhoofd, hebben we gekozen om de OpenSSL API te gebruiken: OpenSSL wordt door alle GNU/Linux PC's op IMEC ondersteund (de Unix PC's nog niet) en valt onder de GPL omdat het met de GNU/Linux distributie meegeleverd is3 . OpenSSL voorziet ook online documentatie, maar deze is helaas nog altijd niet voltooid.
7.1.3 SSL cryptograe Wanneer we onze gegevens willen beveiligen, moeten we een cryptograsch algoritme kiezen samen met een sleutellengte (als die keuze er is). Omdat publieke sleutel encryptie (vanaf nu PKE) traag is, gaat SSL PKE enkel gebruiken voor de uitwisseling van een sleutel voor conventionele (symmetrische) encryptie. Wanneer de client en server de conventionele sleutel beide op een veilige manier verkregen hebben, kunnen ze deze gebruiken voor de verder encryptie van de communicatie. Het is niet nodig om de commando's met een sterk algoritme te encrypteren (wat een grote vertraging zou opleveren) en we hebben slechts de keuze uit de algoritmes beschikbaar op beide hosts. Verder is het, volgens de OpenSSL standaard, vereist dat we geen anonieme encryptie4 gebruiken5 . Ook gaan we geen gebruik maken van MD5 als hash algoritme aangezien er zwakheden bekend zijn (5, Sectie 5.4.1). Voor het zoeken van een geschikte combinatie voor sleuteluitwisseling, authenticatie en encryptie, maken we gebruik van het openssl ciphers commando: 1
$ openssl ciphers -v -tls1 'LOW:!eNULL:!aNULL:!ADH:!MD5:@STRENGTH' Codefragment 7.1:
2 3 4 5
Momenteel niet meer onderhouden http://www.openssl.org/support/faq.html#LEGAL1 Zonder gebruik van sleutels en certicaten zie
man SSL_CTX_set_verify(3)
97
Keuze ciphers
Karel Nijs
Automatisatie van ASIC vericatie
Opmerking: de syntax van het cypher gedeelte van het openssl ciphers commando is hoofdlettergevoelig. De verschillende delen ervan worden gescheiden door een :; een ! zorgt ervoor dat we een bepaalde groep uitsluiten. Met deze selectie hebben we de keuze uit volgende ciphers: 1 2 3 4
$ openssl ciphers -v EDH-RSA-DES-CBC-SHA EDH-DSS-DES-CBC-SHA DES-CBC-SHA
-tls1 'LOW:!eNULL:!aNULL:!ADH:!MD5:@STRENGTH' SSLv3 Kx=DH Au=RSA Enc=DES(56) Mac=SHA1 SSLv3 Kx=DH Au=DSS Enc=DES(56) Mac=SHA1 SSLv3 Kx=RSA Au=RSA Enc=DES(56) Mac=SHA1 Codefragment 7.2:
Beschikbare ciphers
Kx staat voor Key Exchange en bepaalt hoe de sleuteluitwisseling gebeurt. Au betekent Authentication en denieert het algoritme dat gebruikt wordt om het certicaat te tekenen. Enc bepaalt het algortime dat gebruikt wordt voor De Mac is het algoritme gebruikt voor de MAC.
encryption van de berichten.
Tijdens het ontwikkelen van de applicatie hebben we volledige de keuze in handen welk algoritme we willen gebruiken. We moeten wel rekening houden met:
• globale beschikbaarheid, • mogelijke veranderingen bij herinstallatie van de clients of servers, • het algoritme gebruikt om de certicaten te tekenen. We hebben de meeste vrijheid wanneer we geen beperking opleggen aan de combinatie van ciphers. De SSL sockets zijn dan ook op deze manier gecongureerd. 1 2 3
OpenSSL_add_all_algorithms(); //load all algorithms & ciphers OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests();
4
Optie
Beschrijving
-tls1 LOW !eNULL !aNULL !ADH !MD5 !HIGH !MEDIUM @STRENGTH
enkel de algoritmes ondersteund door TLSv1 enkel de ciphers met zwakke encryptie geen ciphers die geen encryptie aanbieden geen ciphers die geen authenticatie aanbieden geen anonieme ciphers geen gebruik van MD5 geen ciphers met sterke encryptie geen ciphers met middelmatige encryptie sortering volgens stijgende sterkte Tabel 7.1:
Opties voor cipher keuze
98
Karel Nijs
5
Automatisatie van ASIC vericatie
res = SSL_CTX_set_cipher_list(ctx, "LOW:!eNULL:!aNULL:!ADH:!MD5:@STRENGTH"); Codefragment 7.3:
Instellen ciphers
7.2 Certicaten Met als doel authenticatie, worden er op voorhand certicaten gegenereerd. In onze applicatie is het vereist dat zowel de client als de server zich authentiseert ten opzichte van de anderen. Bij elk certicaat hoort een sleutelpaar voor asymmetrische encryptie. Dit sleutelpaar moeten we genereren alvorens het certicaat aan te vragen.
7.2.1 Root certicatie authoriteit Om de certicaten te tekenen, moeten we eerst een certicatie authoriteit (vanaf nu CA) opzetten. Wanneer een host de andere host wil valideren, gaat hij dit doen door opnieuw de hash te berekenen van het certicaat. Hierna vergelijkt hij resultaat met de hash gegenereerd en getekend door de CA. Omdat niemand toegang heeft tot de private sleutel van de CA, kan het certicaat niet (kwaadwillig) gewijzigd worden omdat de hash niet opnieuw getekend kan worden. Wanneer beide hosts elkaars CA vertrouwen, kunnen ze beveiligd communiceren. In ons geval is er maar één CA en is deze ook de root CA (hoofd certicatie authoriteit). Eens de root CA gecompromiteerd is, kunnen we niet meer spreken van beveiligde communicatie.
7.2.2 Generatie certicaat Om telkens dezelfde (standaard)opties voor de standaardvelden te gebruiken, hebben we een OpenSSL conguratie le aangemaakt. Je kan deze conguratie le en uitleg over de generatie vinden in de gebruikershandleiding, Appendix C.
7.3 SSLfunctions utility namespace Net zoals we in de aparte Networkfunctions namespace enkele utility functies geherdenieerd hebben (zie 6.2), zijn er een aantal SSL functies geherimplementeerd voor betere werking en foutopvang.
7.3.1 SSLfunctions::SSL_write() Deze functie wordt gebruikt om data te schrijven naar de remote host, geëncapsuleerd in een SSLbericht. Om zeker te zijn dat het volledige bericht verstuurd wordt, gebruiken we een methode die equivalent is aan de writen() methode, vermeld in (10, Hoofdstuk 1).
99
Karel Nijs
Automatisatie van ASIC vericatie
Het schrijven naar een SSL object is haast identiek aan het schrijven naar een socket. Daarom gaan we deze methode ook niet verder bespreken.
7.3.2 SSLfunctions::SSL_read() Wanneer we lezen van een bepaald kanaal kan het hinderlijk zijn dat we blijven blokkeren wanneer de sockets als zodanig gecongureerd zijn. Daarom zijn de leesfuncties geïmplementeerd met het select-mechanisme: we voegen de le descriptor toe aan zowel de lees- als foutset van select(). select() zelf blijft wachten voor een bepaald, vooraf gespecieerd interval. Op deze manier kunnen we zowel data van het kanaal ophalen als fouten detecteren. Deze methode is ineens een oplossing van het interconnectie probleem: er kan namelijk met een beveiligde ASICclient connectie gemaakt worden met de on beveiligde ASICserver (en andersom). Wanneer zich dit voordoet, blijft de leesfunctie hangen. Dit wordt nu echter vermeden door een tijdsinterval te speciëren. In pseudocode krijgen we: 1 2 3 4 5 6
FD_ZERO(&rset); FD_ZERO(&eset); FD_SET(sd, &rset); FD_SET(sd, &eset); tv.tv_sec = TIMEOUT; tv.tv_usec = 0;
7 8 9 10
//read from socket with timeout int res = select( sd+1, &rset, NULL, &eset, &tv );
11 12 13 14 15 16 17 18 19 20 21 22 23
if( res < 0 ) { //The select() function wasn't able to start for reading from SSL socket } else if( FD_ISSET(sd, &rset) ){ //Read from socket res = SSL_read(ssl, buf, count); if(res < 0) out << "Unable to read message in select() from SSL socket"; } else if( FD_ISSET(sd, &eset) ) { //Received error in select() } else if (res == 0 ) { //Timeout in select() while reading from socket } Codefragment 7.4:
read() met timeout
100
Karel Nijs
Automatisatie van ASIC vericatie
7.3.3 Certicaat controle De certicaatscontrole is een belangrijke stap en wordt uitgevoerd met behulp van de SSLfunctions::check_cert() functie. We voeren hier enkel de controle uit van de elementaire velden, aanwezig in elk type X509 certicaat, zoals Subject Name, Issuer Name en email. De controle zelf wordt in principe door OpenSSL gedaan en we zijn vrij wat we met het resultaat hiervan doen. Omdat we natuurlijk enige beveiliging willen, hebben we voor het SSL contextobject de SSL_VERIFY_PEER en SSL_VERIFY_FAIL_IF_NO_PEER_CERT opties gezet (zie 7.4.4). Wanneer we de terugkeerwaarde van de SSL_get_verify_result() functie bekijken, kunnen we beslissen of we door gaan met de connectie6 . De standaardvelden worden opgevraagd en in console weergegeven. We zouden de waarden van deze standaardvelden kunnen vergelijken met vooropgestelde eisen. Zo zouden we bijvoorbeeld, als Subject Name, enkel ASICclient kunnen aanvaarden. Iedereen kan echter dit veld zelf invullen met de waarde die hij wenst (bij certicaatgeneratie tenminste). Wanneer het certicaat dan door de root CA getekend wordt, zou het toegang krijgen tot de diensten van de server. Wanneer we de root CA echter enkel gebruiken om (clients voor) deze applicatie te authenticeren, lijkt de veldencontrole overbodig. Wanneer er echter door IMEC zelf uitgevaardigde certicaten gebruikt zouden worden en het hele personeel toegang heeft, kan overwogen worden de waardes van de velden te controleren. De beheerder heeft de controle over deze situatie volledig in handen.
X509v3 extensies X509v3 extensies worden momenteel niet gebruikt, noch gecontroleerd. De functie SSLfunctions::post_connection_check() staat open voor implementatie en interpretatie. Er zit een standaard voorbeeld in (7, 5.1.3 Peer authentication).
Andere We maken verder nog gebruik van andere utility functies: SSLfunctions::verify_callback() en SSLfunctions::SSL_get_error_info(). Deze zijn afkomstig uit (7) en heb debuggen als doel. 6
Normaal zouden we zelfs niet op dit punt mogen komen met deze contextopties ingesteld!
101
Karel Nijs
Automatisatie van ASIC vericatie
7.4 Client 7.4.1 SSLconn klasse De SSLconn klasse is een abstracte klasse waarmee we functies bundelen die zowel bij de client als server geljkaardig zijn. Zo is er bijvoorbeeld geen verschil in het afsluiten van de connectie aan client- of serverzijde. Wanneer je het UML diagram bekijkt (zie Figuur 6.3.4), valt meteen op dat SSLconn, in tegenstelling tot PlainConn, wél een de structor heeft. Dit komt omdat er expliciet bronnen moeten vrijgegeven worden bij vernietiging van het SSLconn object (zie Codefragment 15). Verder breiden de SSLclient en SSLserver klassen de SSLconn klasse uit met client respectievelijk server specieke functies.
7.4.2 PlainClient klasse Het opzetten van een
on beveiligde connectie is eenvoudig:
1. Maak een adresstructuur aan voor de remote host. We hebben hier voorzien dat de remote host zowel volgens IP als volgens hostname gevonden kan worden door gebruik te maken van de gethostbyname() functie. 2. Maak een socket aan. 3. Connecteer met de server op deze socket. Voor een volledige beschrijving verwijzen we naar (10, Hoofdstuk 4), (14) of (15).
7.4.3 SSLclient klasse Het opzetten van een SSL client is wat ingewikkelder: hierbij moeten we gebruik maken van de certicaten, specieke socket conguratie, . . . We kunnen echter eerst een gewone socket aanmaken en deze na creatie gebruiken om een SSL socket op te zetten. De constructor van de SSLclient klasse is dan ook haast identiek aan deze van PlainClient.
open_conn() In deze functie wordt er eerst geconnecteerd met een gewone socket, vervolgens stellen we de SSL context in en proberen we een vorige sessie te hervatten. Wanneer we een SSL connectie opgezet hebben, is het onze taak om de remote host te controleren. Eens de remote host gevalideerd is, zijn we zeker van een beveiligde connectie. In pseudocode:
102
Karel Nijs
1 2
Automatisatie van ASIC vericatie
Networkfunctions::Socket(AF_INET, SOCK_STREAM, 0, dbg, 2); Networkfunctions::Connect(send_sd, (struct sockaddr*) &remhost, sizeof(remhost), dbg, 2);
3 4 5 6
// initialize SSL stuff ctx = SSLfunctions::init_context( TLSv1_client_method(), ... ); ssl = SSL_new( ctx );
7 8 9 10 11
if( ssl != NULL ) { SSLfunctions::SSL_set_fd( ssl, ... ); SSLfunctions::load_client_session( ssl, ... ); SSLfunctions::SSL_connect( ssl, ... );
12 13 14 15 16 17 18 19
if( SSL_session_reused( ssl ) ) { //Reusing saved SSL session } else { //Saving newly created SSL session SSLfunctions::save_client_session( ssl, get_rhostname(), ... ); }
20 21 22 23 24 25
SSLfunctions::check_cert( ssl, ... ); SSLfunctions::post_connection_check( ssl, ... ); } else { //... } Codefragment 7.5:
SSLclient::open_conn() pseudocode
De SSLfunctions::init_context() uit Codefragment 26 maakt een nieuwe SSL context aan en geeft deze terug. Alle contextafhankelijke instellingen worden in deze functie gemaakt. De andere functies maken dan weer instellingen voor het SSL object. Dit object kan als een connectie gezien worden.
7.4.4 Contextinitialisatie Het is interessant de initialisatie van de context naderbij te bekijken. Deze bepaalt namelijk de conguratie van de SSL sessie en verschilt haast niet tussen client en server. De eerste stap is het initialiseren van de SSL bibliotheek en het laden van alle algoritmes en foutberichten (je kreeg hier al een sneak preview van in Codefragment 6). Wanneer we de initialisatiefunctie opgeroepen hebben met als doel een TLSv1_server_method() aan te maken en wanneer er al een context bestaat, wordt er onmiddellijk teruggekeerd: de context parameters zijn dan immers al ingesteld.
103
Karel Nijs
Automatisatie van ASIC vericatie
Vervolgens gaan we de SSL pseudo-randomgenerator initialiseren. Het gebruikte algoritme komt uit (7, 4.4.1 Seeding the PRNG). Vervolgens voeren we volgende stappen uit: 1. Aanmaken context object. 2. Instellen van de mogelijke ciphers (zie Codefragment 6). 3. Contextopties instellen: alle beschikbare patches worden geladen zodat we zeker alle bekende bugs verhelpen. Hierna stellen we nog eens expliciet in dat het SSLv2 protocol niet mag gebruikt worden. 4. We laden het certicaat van de Certicatie Authoriteit: hiermee worden de certicaten van de communicerende hosts gevalideerd. Na het inladen stellen we de vericatie-opties en -diepte in: we willen dat zowel de client als de server een certicaat voorlegt, dat de verbinding mislukt wanneer dit niet lukt en de vericatiediepte van het laagste niveau is. 5. Voor dat we ons eigen certicaat en private sleutel kunnen laden, moeten we een callback functie voorzien. Zonder deze functie zou SSL in de console naar het paswoord vragen. Omdat de eindgebruikers deze prompt niet te zien krijgen (ze zijn namelijk met de GUI aan het werken), is dit niet gewenst. Wanneer we echter een callback functie deniëren, moeten we ook precies speciëren waar SSL het paswoord moet zoeken. We kunnen het paswoord in een bestand opslaan, maar dit zou dan ook weer geëncrypteerd moeten gebeuren, waar je ook een paswoord voor nodig hebt. . . Bij IMEC zien ze het niet zitten om bij opstarten van de GUI telkens een paswoord in te moeten geven om toegang te krijgen tot dit certicaat. Tijdens het schrijven van deze sectie zit het paswoord hard gecodeerd in de functie. Dit is zeker niet de geschikte oplossing: je kan namelijk stringconstanten terugvinden in de gecompileerde code wanneer je deze opent in een eenvoudig tekstverwerkingsprogramma zoals Kwrite. Demonstratie van het probleem: 1 2 3
4
//do not ask for password from stdin //@danger must BOTH be set BEFORE using the certificate and keys ! SSL_CTX_set_default_passwd_cb_userdata( ctx, const_cast( "..." ) ); SSL_CTX_set_default_passwd_cb( ctx, pem_passwd_cb ); Codefragment 7.6:
Instellen password callback functie
104
Karel Nijs
Automatisatie van ASIC vericatie
Een andere oplossing zou een leeg paswoord in het certicaat zijn. Het certicaat kan dan wel kwaadwillig gewijzigd worden door iemand met beheersrechten, maar de hash (ondertekent door de CA) zal echter niet valideren. Zo kan het certicaat toch als ongeldig beschouwd worden. Standaard kan je met OpenSSL geen publieke sleutels aanmaken met lege paswoorden. Dit is ook niet gelukt door zelf een OpenSSL conguratie le op te geven. Wanneer op enig punt tijdens de initialisatie iets fout zou gaan, wordt er haast onmiddellijk een ASICexception geworpen: het opzetten van de sessiecontext is essentieel voor een met SSL beveiligde verbinding. Ik heb hier geen codevoorbeelden van opgenomen omdat de initialisatie van de SSL context redelijk standaard is.
7.4.5 Client side session caching In Codefragment26 wordt de SSLfunctions::load_client_session() functie opgeroepen. Dit is een oplossing voor het hergebruik van sessies. Zoals eerder besproken kan het opzetten van de SSL sessie even duren en vermijden we best deze overhead wanneer mogelijk. We gaan na elke geslaagde connectie de huidige sessie geëncrypteerd opslaan op het bestandssysteem. Omdat de sessie speciek is voor een connectie met een bepaalde server, gaan we voor elke verschillende server een bestand met instellingen bijhouden. Niemand kan dit bestand lezen, tenzij ze over het paswoord van het gebruikte SSL certicaat beschikken. Wanneer we de volgende keer proberen te connecteren met de server gaan we eerst lokaal kijken of we een opgeslagen sessie ter beschikking hebben. Zo niet wordt er helemaal geen fout gegenereert, maar een nieuwe sessie opgezet. Alle afspraken tussen de hosts7 moeten opnieuw gemaakt worden. De sessie-informatie wordt in een lokale le opgeslagen in de /tmp directory. We hebben voor deze manier gekozen omdat deze directory op elk systeem altijd aanwezig zal zijn. Zouden we het opslaan toelaten in een gebruikersspecieke directory, kan dit problemen opleveren op gebied van permissies en aanwezigheid8 en gaat de snelheidswinst verloren. Een uitgedunde versie van de implementatie van sessie 1
2
opslag vind je in Codefragment 46 terug:
int SSLfunctions::save_client_session(SSL* ssl, string rhostname, Debug *dbg, int loglevel) { //...
3 4 7
filename = SSLfunctions::getSessionFilename(rhostname);
Het gebruik van de term
peer
zou hier niet correct zijn omdat in SSL er altijd een client en een server is.
Nochthans wordt deze wel gebruikt in de documentatie.
8
Een gebruiker mag alles in zijn home veranderen, maar bijvoorbeeld niet de naam van
105
/tmp
Karel Nijs
Automatisatie van ASIC vericatie
5
//open file for writing int fd = open( filename.c_str(), O_CREAT | O_RDWR | S_IRUSR | S_IWUSR);
6 7 8
//set file lock struct flock lock; lock.l_type = F_WRLCK; fcntl( fd, F_SETLK, (struct flock*)&lock ); sesfile = fdopen( fd, "w+" );
9 10 11 12 13 14 15
if ( sesfile != NULL) { SSL_SESSION* ses = SSL_get1_session( ssl );
16 17 18
if( ses != NULL ) { res = PEM_write_SSL_SESSION( sesfile, ses ); }
19 20 21 22 23
//extra test to avoid double error reporting code if( ses==NULL || res < 0 ) //Failed to save SSL session to file
24 25 26 27
if( ses != NULL ) SSL_SESSION_free( ses );
28 29 30
res = 0; } else { //Failed to create file for saving SSL section res = -1; }
31 32 33 34 35 36 37
// close the file fclose(sesfile); close(fd); lock.l_type = F_UNLCK; fcntl( fd, F_SETLK, (struct flock*)&lock );
38 39 40 41 42 43
return res;
44 45
} Codefragment 7.7:
SSL client side session caching
Het algoritme van SSLfunctions::load_client_session() is analoog. Er wordt hier gebruik gemaakt
le locks om inconsistenties te voorkomen wanneer de gebruiker
106
Karel Nijs
Automatisatie van ASIC vericatie
meerdere keren vanaf dezelfde host een bepaalde server zou contacteren en dezelfde le heropend zou worden. De flock() functie wordt hier niet gebruikt wegens incompatibiliteit met het HP-UX platform. OpenSSL voorziet zelf geen oplossing voor de implementatie van sessiecaching. De informatie zowel online als in (7) is beknopt en in pseudocode.
7.4.6 close_conn() Het afsluiten van een SSL connectie is een gecompliceerd proces (zie man SSL_shutdown). Wanneer je de sessie wilt hergebruiken (een mogelijkheid die wij willen benutten), moet je tweemaal de SSL_shutdown() functie oproepen. Omdat de context bij de client vernietigd wordt na gebruik (een client zal namelijk via de Tcl C extensie maar éénmaal gebruik maken van zijn context), zouden we de SSL verbinding ook kunnen sluiten met één aanroep. Omdat we niet zeker zijn hoe de server zal reageren op dit quick en dirty afsluiten en om sessieresumptie te garanderen, gebruiken we bij zowel de client als de server de aangeraden methode. 1 2 3 4 5 6 7
int SSLconn::close_conn() { if( ssl != NULL) { int res = SSL_shutdown( ssl ); if( res == 0 ) res = SSL_shutdown( ssl ); //call shutdown for the second TIME else if( res == -1 ) dbg->write("Unable to shutdown SSL connection", __FUNCTION__, 1);
8
//free memory SSL_free( ssl );
9 10
}
11 12
return Networkfunctions::close_socket(send_sd);
13 14
} Codefragment 7.8:
Sluiten SSL verbinding
7.5 Server Na de clientimplementatie bekeken te hebben, kunnen we een blik werpen op deze van de server. Ook bij de SSLserver klasse is er meer werk om de verbinding tot stand te brengen dan bij de PlainServer klasse.
107
Karel Nijs
Automatisatie van ASIC vericatie
7.5.1 PlainServer klasse Zoals eerder uitgelegd wordt de PlainServer klasse opgebouwd of gecongureerd in de Listener klasse. De luisteraar heeft immers een socket waarnaar hij luistert. Binnenkomende clients worden geaccepteerd op hun eigen socket. Op dit instellen na zijn er geen verschillen tussen de client en server.
7.5.2 SSLserver klasse Net zoals bij de SSLclient moet de server zijn context initialiseren bij opstarten. We herbruiken hiervoor de SSLfunctions::init_context() functie, maar nu met de parameters van de server: servercerticaat, private sleutel en ook de TLSv1_server_method() methode. Het is een veel gemaakte fout bij de initialisatie van beide hosts een TLSv1_client_method() of TLSv1_server_method() methode op te geven. De connectie gaat echter niet opgezet kunnen worden op deze manier (OpenSSL kan slecht met deze fout om) omdat, zoals eerder vermeld, de beide hosts in een SSL interactie niet als gelijken (peers) beschouwd kunnen worden.
7.5.3 Server side session caching Een methode die we onderzocht hebben, is de implementatie van sessie opslag aan de serverzijde. Net zoals bij de client kunnen we immers beslissen de sessie-informatie op te slaan voor hergebruik. De implementatie van server side session caching op schijf is ingewikkeld en ongedocumenteerd. We blikken even terug op de client side caching: hier gebruikten we on disk caching omdat de SSL context objecten na elk gebruik van het, door ons ontwikkelde, ::nwservice::my_socket commando de objecten uit het geheugen verwijderd werden. De server service is echter bedoeld om altijd in het geheugen geladen te blijven. Wanneer we dus zorgen dat het sessie context object niet vernietigd wordt bij het beëindigen van een ASICserver, kunnen we de context hergebruiken. We moeten dus een globale variabele bijhouden waarin we deze context kunnen opslaan. Vooraleer we hiermee verder gaan, willen we de lezer eraan herinneren dat de luisteraar helemaal niets af weet van de implementatie van onderliggende socketlaag. Aan de hand van een command line parameter weet de luisteraar enkel dat hij een SSLserver object moet aanmaken, maar hij slaat dit op in een IConnection object (zie Codefragment 9). De SSL context wordt dus ook aangemaakt door het (SSLserver) connectie-object en niet door de luisteraar. Wanneer we willen dat deze context hergebruikt kan worden, moet hij beschikbaar zijn voor alle ASICserver objecten (huidige en volgende). Dit probleem is weer opgelost met een statische variabele in een globale namespace (zie 6.5.1), maar deze keer in de SSLfunctions namespace.
108
Karel Nijs
Automatisatie van ASIC vericatie
De allereerste keer dat er een context aangemaakt wordt, wordt deze opgeslagen in de globale SSLfunctions::gctx variabele. Alle volgende SSLserver objecten maken hiervan gebruik9 . Voor dat we de sessiecontext kunnen hergebruiken, moeten we hem eerst uniek kunnen identiceren. Hiervoor wordt de SSLfunctions::SSL_CTX_set_session_id_context() functie gebruikt. Dit is een aangepaste functie die altijd dezelfde ID genereert voor de server (in tegenstelling tot de SSLfunctions::getSessionFilename() functie die voor elke server apart een sessiebestandsnaam genereert). Omdat de SSLfunctions::init_context() onmiddellijk terugkeert wanneer de SSLfunctions::gctx variabele ingevuld is, kan het voor komen dat de creatie van het volgende SSL object mislukt omdat de context niet meer geldig is. Omdat we niet zeker weten wanneer dit kan voorkomen, controleren we het aanmaken van het nieuwe SSL object met SSL_new() tweemaal. Wanneer deze functie de NULL waarde teruggeeft, gaan we opnieuw proberen een SSL object aan te maken, maar we resetten de globale variabele gctx. Dit heeft geen desastreuze gevolgen: tijdens de eerst volgende SSL connectie wordt opnieuw een context object met dezelfde sessie ID aangemaakt.
open_conn() Naar analogie met BSD sockets vind je aan de serverzijde een acceptatiefunctie terug, maar nu voor SSL connecties. Bij open_conn() van de SSLclient daareentegen kon je een connectiefunctie terugvinden. De implementatie SSLserver::open_conn() wordt echter gedomineerd door caching opdrachten. In pseudocode wordt dit: 1 2
ctx = SSLfunctions::init_context( TLSv1_server_method(), ... ); ssl = SSL_new(ctx);
3 4 5 6 7 8 9
//check for invalid context if( ssl == NULL ) { SSL_CTX_free( SSLfunctions::gctx ); SSLfunctions::gctx = NULL; ctx = SSLfunctions::init_context( TLSv1_server_method(), ... ); }
10 11 12
if( ssl != NULL ) { SSLfunctions::SSL_set_fd( ssl, ... );
13 14 15 9
//session caching SSLfunctions::SSL_CTX_set_session_id_context( ctx, SERVER_SESSION_ID, ... );
In Java zou je zo'n object kunnen initialiseren met een
109
static synchronised
methode
Karel Nijs
16
Automatisatie van ASIC vericatie
SSL_CTX_set_timeout( ctx, ... );
17 18 19 20
//accept client SSL_set_accept_state( ssl ); SSLfunctions::SSL_accept( ssl, ... );
21 22 23 24 25 26 27
//verifiy client SSLfunctions::check_cert( ssl, ... ); SSLfunctions::post_connection_check( ssl, ... ); } else { //... } Codefragment 7.9:
SSLserver::open_conn() pseudocode
7.6 Lessenpakket Tijdens de voorstelling van de eindwerkposter (aanwezig op de CD-ROM in bijlage) heeft een docent me gevraagd of de mogelijkheid er was om SSL sockets op te nemen in het lessenpakket. Het begrip SSL sockets klinkt weliswaar heel rudimentair, maar net hierom komt er veel bij kijken. Tijdens de eerste licentie Industrieel Ingenieur Informatica wordt er, toevallig door mijn interne promotor Joachim Van Meirvenne, het vak Netwerkprogrammatie gegeven10 . Hier krijgen de leerlingen een eerste kennismaking met socketprogrammatie op het *nix platform: TCP sockets, concurrent servers, multiplexing I/O, non-blocking I/O, . . . Wanneer een leerling deze leerstof beheerst kan de overstap naar SSL socketprogrammatie makkelijk(er) gemaakt worden. SSL voorziet zelfs de mogelijkheid om met BIO sockets te werken.
7.6.1 BIO sockets BIO sockets voorzien een trivale interface voor het gebruik van SSL; net zoals met gewone sockets kan je met eenvoudige functies connecteren, accepteren en interageren. Een eenvoudige SSL client zou er zo uit kunnen zien: 1 2
//setting up socket and making connection send_sd = get_tcp_socket(&server);
3 4 5 6
//initialize SSL stuff BIO* bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); SSL_CTX* ctx = init_context(bio_err, TLSv1_client_method());
7 8 10
SSL* ssl=SSL_new(ctx);
Naar deze cursus is ook regelmatig verwezen in deze tekst
110
Karel Nijs
Automatisatie van ASIC vericatie
9 10 11 12 13
if (ssl) { BIO *sbio = BIO_new_socket(send_sd, BIO_NOCLOSE); SSL_set_bio(ssl, sbio, sbio); int res;
14 15 16 17 18 19 20 21 22
if( (res = SSL_set_fd(ssl, send_sd)) == 0 ) { //Unable to SSL_set_fd } else { //make connection if( (res = SSL_connect(ssl)) <= 0 ){ berr_exit(bio_err, "Unable to SSL connect\n"); } else { check_cert(ssl, server, bio_err);
23
if( (res = post_connection_check(ssl, server)) < 0 ) //failed to verify
24 25
}
26 27
}
28 29 30 31 32
BIO* bio = BIO_new_ssl_connect(sslctx); BIO_get_ssl(bio, & ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); BIO_set_conn_hostname(bio, server ":" port);
33 34 35 36 37 38 39 40 41
if( (res = BIO_do_connect(bio)) <= 0 ){ //Error attempting to connect BIO_free_all(bio); SSL_CTX_free(sslctx); } } else { //Unable to create ssl obj } Codefragment 7.10:
Client met SSL BIO sockets
Eén van de eerste versies van onze applicatie gebruikte ook BIO sockets (vandaar de code). Later zijn we hier vanaf gestapt omdat de luisteraar eenvoudiger te implementeren was op de klassieke manier. De client is gevolgd uit conventionele overwegingen. Achteraf bekeken zou de implementatie van de SSLclient en SSLserver vereenvoudigd kunnen worden, zouden we het gebruik van BIO sockets doordrijven.
7.6.2 Theoretische basis Voor een SSL connectie op te kunnen zetten, moeten de leerlingen ook eerst de theoretische werking van SSL gezien hebben. Deze hebben we tijdens het eerste semester van de tweede
111
Karel Nijs
Automatisatie van ASIC vericatie
licentie in het vak Beveiliging Theorie (5) gezien. Eens de theoretische werking gezien, kan er een labo over certicaten en PKI gegeven worden. Deze benadering hebben we dan ook gevolgd tijdens de (labo)lessen in het tweede semester. SSL socketprogrammatie als vak zou geschikt zijn wanneer zowel de theoretische basis, als de elementaire netwerkprogrammatie gezien is. Zo niet, zou er veel tijd verloren gaan in het zoeken naar mogelijke werkwijzen en oplossingsmethoden, maar dit geldt natuurlijk voor elk vak.
7.6.3 Toepassingen in real life Het programmeren met SSL sockets kan leerlingen iets bijbrengen over de interne werking van SSL en het eectief opzetten van een beveiligde verbinding. Ik denk echter dat bedrijven, die niet met ontwikkeling bezig zijn, eerder een meer conventionele en voorgeïmplementeerde methode zullen aanwenden. Er kruipt tijd en werk in om een beveiligde SSL communicatie te ontwikkelen. Maar als je gebruik maakt van bepaalde afspraken (zoals bijvoorbeeld ons ASICproto), kan je tijd winnen door codehergebruik voor volgende applicaties. Bij een doorgedreven gebruik van SSL zou er handtekenen van code met behulp van PKI certicaten gezien worden. Deze praktijk wordt haast altijd toepast op het Internet wanneer er pakketten publiek beschikbaar gemaakt worden en heeft als doel integriteit en authenticiteit te garanderen. Gewoonlijk stelt men de hash ter beschikking, al dan niet gehandtekend met de private sleutel.
112
Hoofdstuk 8
Besluit Het lokaal uitvoeren van checks met deze applicatie zou een eenvoudige opgave geweest zijn. Wanneer we echter als doel distributiviteit, executie-uitstel, beveiliging, enz hebben, mét beperkte middelen, wordt het een heel ander probleem. Voor we het ontwerp en implementatie van de Automatisatie van ASIC vericatie applicatie startten, hebben Erwin en ik samen een stappenplan opgesteld. Dit stappenplan was opgesteld zonder rekening te houden met het zelf te implementeren protocol, server service en SSL beveiliging ervan. In januari werd het dan ook duidelijk dat dit stappenplan niet meer toereikend was en zijn we hier van moeten afwijken. We hebben alle vooropgestelde eisen en uitbreidingen gehaald, op één na: de HP-UX compatibiliteit. Zoals eerder vermeld in 6.1.4 hebben we veel tijd besteed aan het compileren op het HP-UX v11.0 platform omdat er conicten waren in de bibliotheken. Toen uiteindelijk de compilatie gelukt was, kwamen er fouten voor in de OpenSSL bibliotheken. Ik ben er zeker van dat deze opgelost kunnen worden, mits er nog tijd in gestoken wordt. Het HP-UX probleem is een tijdelijk probleem voor IMEC: ze plannen in de toekomst een volledige overschakeling naar het GNU/Linux platform. Eerst moet hier natuurlijk wel alle EDAsoftware beschikbaar voor zijn. Op het moment van schrijven, kan de INVOMEC afdeling gebruik maken van onze applicatie en Calibre checks uitvoeren en opvolgen. Onze gegenereerde rapporten worden zonder wijzigingen naar de klant gestuurd. Bij de ingebruikname van het eindwerk moet de huidige GDS- en rules le directorystructuur overgezet worden naar de projectaccount. Tijdens deze transfer gaat IMEC ineens ook de directory's opkuisen: nu zitten er namelijk nog vele oude versies van rules les en andere bestanden in. Ook gaan de rules les de juiste extensies gegeven worden1 . 1
Dit is niet verplicht, maar leidt wel tot makkelijker gebruik van de GUI
113
Karel Nijs
Automatisatie van ASIC vericatie
Omdat dit alles nogal een delicate operatie is, zal het eerst half jaar onze applicatie parallel met het gewone bedrijfsgebeuren gebruikt worden. Na deze inleidende periode wordt de denitieve beslissing tot overschakeling genomen. Tijdens de ontwikkeling is er op gelet dat alle code goed (en in de juiste taal) gedocumenteerd werd. De installatiehandleiding beschrijft gedetailleerd het opzetten van de applicatie en behandelt de mogelijkheid tot upgrades van de afhankelijke pakketten. Ook de generatie van de API('s) en man pages hebben we voor onze rekening genomen. Dit alles resulteert in een optimaal onderhoudbare applicatie, mits enige programmeerervaring.
114
B¼lage A
Flowcharts A.1 Editeren rules le
Figuur A.1:
De gebeurtenis bij een klik op de Edit knop voor elke check
115
Karel Nijs
Automatisatie van ASIC vericatie
A.2 Uitvoeren Calibre check
Figuur A.2:
De rules le controle voor een calibre check
A.3 Check executie wachtrij
116
Karel Nijs
Automatisatie van ASIC vericatie
Figuur A.3:
De werking van de check executie wachtrij
117
B¼lage B
Man pages B.1 runasicgui
118
RUNASICGUI
file:///home/karel/eindwerk_CVS/eindwerk/eindwerk/man/runasicgui.html
RUNASICGUI NAME SYNOPSIS DESCRIPTION OPTIONS FILES BUGS AUTHOR
NAME runasicgui
start up the GUI for the verification of ASICs
SYNOPSIS runasicgui [-offline] [- securityType ] [-silent oneOrzero ]
DESCRIPTION runasicgui starts up a Tcl/Tk GUI for automating the verification of GDS files against rules files. The checks are run on remote servers using plain text security (=none!) or SSL client-server security. You should run this program so you’ll have access to the GDS and rules file locations.
OPTIONS -i -silent 0
Display application information and exit. Start the GUI with debugging and error information printed to konsole. If debugging information is wanted, you should explicitly set this option.
-silent 1 -plain -ssl -offline
Starts the GUI silently (only showing errors in konsole) (default). May be omitted. Use plain text security (=none!). If no security is wanted, you should explicitly set this option. Use SSL client security (default). May be omitted. Start the gui without contacting the remote servers first. Setting
RUNASICGUI
file:///home/karel/eindwerk_CVS/eindwerk/eindwerk/man/runasicgui.html
--help --version
this option will decrease application startup time a lot. Print help information to konsole. Print application version to konsole.
FILES ./verification.sh The Bash script which fires up the GUI. This script should not be called.
BUGS No known bugs in the GUI for so far.
AUTHOR Karel Nijs
Karel Nijs
Automatisatie van ASIC vericatie
B.2 runasicserver
121
RUNASICSERVER
file:///home/karel/eindwerk_CVS/eindwerk/eindwerk/man/runasicserver...
RUNASICSERVER NAME SYNOPSIS DESCRIPTION OPTIONS FILES BUGS AUTHOR
NAME runasicserver
start up the server service for execution of ASIC checks
SYNOPSIS runasicserver <port> [-silent] [- securityType ]
DESCRIPTION runasicserver starts up a concurrent server which listens for connecting clients at the specified port, using the ASICproto protocol. If the connection is successfull, the given command will be executed.
OPTIONS -silent -plain -ssl -h, -help
Starts the server silently (only showing errors in konsole) (default). May be omitted. Use plain text security (=none!). If no security is wanted, you should explicitly set this option. Use SSL client security (default). May be omitted. Print help information to konsole.
FILES ./executioner The executable that runs the received command (from the client) in
RUNASICSERVER
file:///home/karel/eindwerk_CVS/eindwerk/eindwerk/man/runasicserver...
a seperate process. This executable should not be called.
BUGS Receives Abort() signal sometimes.
AUTHOR Karel Nijs
B¼lage C
Installation manual
124
Academiejaar 2005 - 2006
Departement Industriële Wetenschappen BME - CTL
Schoonmeersstraat 52 - 9000 Gent
INSTALLATION MANUAL
Karel NIJS Promotors: Dhr. Joachim VAN MEIRVENNE (Hogeschool Gent, Gent) Dhr. Erwin DEUMENS (IMEC Heverlee, Leuven) Dhr. Kristof LOOTS (IMEC Heverlee, Leuven)
Contents 1 System demands
1
1.1
HP-UX requisities
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.2
Upgrading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
2 Directory structure
3
2.1
Permissions
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.2
The structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.3
The toplevel
. . . . . . . . . . . . . . . . . . . . . . . .
4
2.4
The
. . . . . . . . . . . . . . . . . . . . . . . .
5
2.5
The les . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
guiasic/ directory . . guiasic/eindwerk/ directory .
3 SSL certicate generation
8
3.1
Setting up the environment
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
3.2
Creating a self-signed root certicate . . . . . . . . . . . . . . . . . . . . . . . .
8
3.3
Creating certicates for client and server . . . . . . . . . . . . . . . . . . . . . .
9
3.3.1
Client certicate
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.3.2
Server certicate
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
4 Setting up the server 4.1
Compilation of the server service
4.2
Execution of the server service
11 . . . . . . . . . . . . . . . . . . . . . . . . . .
11
. . . . . . . . . . . . . . . . . . . . . . . . . . .
11
5 Setting up the GUI (client)
13
5.1
Compilation of the client's shared object . . . . . . . . . . . . . . . . . . . . . .
13
5.2
Execution of the GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
6 Application specic
15
6.1
Settings
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
6.2
Manual pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
6.3
Maintenance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
6.4
Global . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
6.5
Check execution
16
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Appendices
17 i
Karel Nijs
Automatisation of ASIC verication: Installation manual
A OpenSSL root CA conguration le
18
B OpenSSL client conguration le
20
C Application conguration le
22
Bibliography
24
ii
Chapter 1
System demands For installation of the Automatisation of ASIC verication application, you should have at least the following software installed:
•
a *nix operating system,
•
the GNU GCC compiler: version 3.3.5+,
•
Tcl: version 8.3+,
•
Tk: version 8.3+,
•
Tix: version 8.1+,
•
the OpenSSL library: version 0.9.8a+.
If you want to extend the C++ application, you must recompile it. These tools might come in handy:
•
KDevelop: IDE for writing C/C++ (and other) applications,
•
Kopete: IDE for writing Tcl/Tk (and other) applications,
•
GNU GDB: debugger,
•
Valgrind: memory leak checker,
•
strace: console tool for debugging.
1.1 HP-UX requisities On the HP-UX platform, you need the OpenSSL source les adjusted by the HP company. You can nd them at http://hpux.cs.utah.edu/hppd/hpux/Languages/openssl-0.9.8a/.
1
Karel Nijs
Automatisation of ASIC verication: Installation manual
If you're (still) using HP-UX v11.x you need to install GNU GCC 4.0.2, since GNU GCC 2.95 is not compatible with this HP-UX version. When you want to adjust the
Makele.hpux
le, do
not
set the -g option for compilation.
HP-UX v11.x is known to have problems with this option. The
strace
package is currently not available at the HP-UX servers, when needed you can
nd it at http://hpux.asknet.de/hppd/hpux/Sysadmin/trace-1.6/.
1.2 Upgrading When upgrading the OpenSSL library you should recompile it on each architecture (64bit GNU/Linux and HP-UX) and link the newly compiled libraries with this program's executables. Upgrading to a higher GNU GCC version had no known complications, for now.
2
Chapter 2
Directory structure The application directory structure may seem overwhelming if you're new to the application. But after installation, you won't need this structure anymore: you can easily run the GUI with just one command without knowing anything about the directory structure.
Regular
users shouldn't know about the structure at all: they will only be using the command
line execution.
2.1 Permissions Before we'll take a look at the specic directories and their contents, lets set the permissions. You can nd the project account data in Table 2.1. Set the application directory's permissions:
1 2
$ chmod o-rwx,g-rwx ~guiasic/eindwerk/ -Rv $ chmod o-rwx,g-rwx ~guiasic/networklayer_source/ -Rv Code fragment 2.1:
Now all
other
Set directory permissions
users aren't allow to read, write or execute les and directories.
If we want to let them use the application we should set the
user group home shell compiler
SUID
guiasic guiasic /imec/other/guiasic/ /imec/software/central/bin/bash /imec/software/gcc/4.0.2/HPUX11/bin/g++ Table 2.1:
Project account data
3
bit and give them read and
Karel Nijs
Automatisation of ASIC verication: Installation manual
1
execute permissions on the executable :
1
$ chmod u+s,o+rx ~guiasic/eindwerk/runasicgui -v Code fragment 2.2:
Set runasicgui permissions
Of course, they also need read and execute permissions on the toplevel program directory:
1
$ chmod g+rx,o+rx ~guiasic/eindwerk/ Code fragment 2.3:
Set toplevel directory permissions
2.2 The structure
Figure 2.1:
Directory structure
2.3 The toplevel guiasic/ directory 1 2 3
drwx------ eindwerk drwx------ EUROPRACTICE drwx------ networklayer_source Code fragment 2.4:
eindwerk directory structure
Directory guiasic/EUROPRACTICE/ Contains all the GDS-les and rules les available for the dierent technologies.
1
This executable has to be compiled rst (see Section 5.1)! 4
Karel Nijs
Automatisation of ASIC verication: Installation manual
Directory guiasic/networklayer_source/ This directory contains all the C++ source les and API.
2.4 The guiasic/eindwerk/ directory 1 2 3 4 5 6 7 8 9 10 11
drwx-----drwx-----drwx-----drwx-----drwx-----drwx-----drwx-----drwx-----drwx------rwx------rw-------
checks config man modules networklayer PICS scripts secure tmp runasicgui runasicgui.cpp Code fragment 2.5:
eindwerk directory structure
Directory checks/ This directory contains the Tcl scripts for each specic check. There's also a le,
skeleton.tcl, which should be used for designing new Tcl scripts for future
checks. You could compare it to the
/etc/skeleton
functionality.
Directory config/ This directory contains all the conguration and settings les.
application_settings.tcl style.tcl
Contains the application settings (pe. the
Gscan
command)
Contains all fonts and settings for labels, headers, . . .
Adjustments here will have a global eect on the look of the GUI.
testcase.tcl
This le should only be used for debugging purposes:
you can use it to set
default values for all the elds of the GUI.
application.conf
Contains the dierent checks, EDA's and remote servers.
Checks, EDA's and/or servers should only be added/adjusted here.
Directory man/ Contains the man pages of the application.
5
Karel Nijs
Automatisation of ASIC verication: Installation manual
The man pages are available as gro and HTML format and are located in the
man/7
subdi-
rectory. For (re)generating the HTML manual pages, we refer to Section 6.2.
Directory modules/ All the Tcl scripts are located here.
Directory networklayer/ The (compiled) Tcl C extension of the network layer should be placed here. For more information on this, see Section 5.1.
Directory PICS/ This directory contains the used images for the GUI. All these images are copyrighted, but for this thesis project we have permission from Everaldo (http://www.everaldo.com). You can view the licence in the
PICS/licence.lic
le.
Directory scripts/ Contains Bash scripts which are executed on remote servers for gathering information, setting (Shell) options, preparing Calibre checks, . . . See Section 6.5 for more information on preparing Calibre checks.
verication.sh
Script which runs the Tix interpreter with the
server_monitor.sh
Prints the output of the
modules/main.tcl Tcl script.
top or ps command to standard out (platform
dependent).
Directory secure/ This directory should
certainly not
be accessible by any other user then the user of the project
account, since it contains the client, server
and
root CA certicates!
Also the Tcl script that generates the pass phrase to be exchanged between the client and the server is stored here and must be kept secret.
Directory tmp/ This temporary directory is used for creating and storing temporary application les when the working directory is not (yet) set.
6
Karel Nijs
Automatisation of ASIC verication: Installation manual
2.5 The les File runasicgui This command is executed by all users for starting up the GUI. As described above, you should set the SUID bit and correct permissions on this executable.
File runasicgui.cpp The C++ source le for the
runasicgui
command.
7
Chapter 3
SSL certicate generation 3.1 Setting up the environment Since we're having
only one
CA which also functions as the root CA, we only have to set up
one CA environment. This environment should
only once
be installed: the rst time setting up the application.
For more information than just the commands we refer to (1, Section 3.3).
1 2 3 4 5 6 7
$ $ $ $ $ $ $
mkdir ~guiasic/eindwerk/secure/ca cd ~guiasic/eindwerk/secure/ca mkdir certs private chmod g-rwx,o-rwx certs chmod g-rwx,o-rwx private echo '01' > serial touch index.txt Code fragment 3.1:
Setting up the CA environment
3.2 Creating a self-signed root certicate Because the root CA is the highest authority for us, this CA is allowed to sign its own certicate. The root CA will also be responsible for validating and signing the certicate
requests
for
other hosts. For generating the root CA certicate we need a specic OpenSSL conguration le. You can nd an example in Appendix A. In this le you should
1 2 3
certainly
suply the
dir
variable.
$ cd ~guiasic/eindwerk/secure/ca $ OPENSSL_CONF=~guiasic/eindwerk/secure/ca/openssl_rootca.cnf $ export OPENSSL_CONF 8
Karel Nijs
4 5 6
Automatisation of ASIC verication: Installation manual
$ openssl req -x509 -newkey rsa -out certs/rootca_cert.pem -outform PEM Enter PEM pass phrase: Verifying - Enter PEM pass phrase: Code fragment 3.2:
Creating a self-signed root certicate
3.3 Creating certicates for client and server 3.3.1 Client certicate First generate the client's private key. We were
not
able to nd a solution for a blank pass
phrase here. This is the reason why the pass phrase must be hard coded into the C++ source les. For generating the client certicate we also need a specic OpenSSL conguration le. You can nd an example in Appendix B. You can skip the rst command if you haven't changed directory yet. Do
not 1 2 3 4 5 6 7
forget to reset the
OPENSSL_CONF
path here!
$ cd ~guiasic/eindwerk/secure/ca $ OPENSSL_CONF=~guiasic/eindwerk/secure/ca/openssl_client.cnf $ export OPENSSL_CONF $ openssl req -newkey rsa -keyout certs/client_key.pem -keyform PEM \ -out certs/client_req.pem Enter PEM pass phrase: Verifying - Enter PEM pass phrase: Code fragment 3.3:
Generate the client's private key
Next generate the clients certicate. You need the root CA's pass phrase for this.
1 2 3 4 5
$ openssl x509 -req -in certs/client_req.pem -extfile ./openssl_client.cnf \ -extensions v3_req -CA certs/rootca_cert.pem -CAkey private/rootcakey.pem \ -CAcreateserial -out certs/client_cert.pem Enter pass phrase for private/rootcakey.pem: $ cat certs/client_cert.pem certs/client_key.pem certs/rootca_cert.pem > certs /client.pem Code fragment 3.4:
The
certs/client.pem
Generate client certicate
le is needed when using SSL sockets.
You can view the certicate with:
1 2
$ openssl x509 -subject -issuer -noout -in certs/client.pem subject= /CN=client/ST=Vlaams-Brabant/C=BE/emailAddress=noemail@EUROPRACTICE. be/O=IMEC/OU=EUROPRACTICE 9
Karel Nijs
3
Automatisation of ASIC verication: Installation manual
issuer= /CN=rootCA/ST=Vlaams-Brabant/C=BE/[email protected] /O=IMEC/OU=EUROPRACTICE Code fragment 3.5:
View client certicate
3.3.2 Server certicate The last part is generating the server's certicate. The server certicate conguration le resembles the client's a lot. You can nd the client's example in Appendix B. You should replace every occurrence of client with server and save it to
guiasic/eindwerk/secure/ca/openssl_server.cnf. 1
We advise you to use the same pass phrase for the client and server, just to keep it simple . You can skip the rst command if you haven't changed directory yet. Again: do
1 2 3 4 5 6 7 8 9 10 11 12
not
forget to reset the
OPENSSL_CONF
path here!
$ cd ~guiasic/eindwerk/secure/ca $ OPENSSL_CONF=~guiasic/eindwerk/secure/ca/openssl_server.cnf $ export OPENSSL_CONF $ openssl req -newkey rsa -keyout certs/server_key.pem -keyform PEM \ -out certs/server_req.pem Enter PEM pass phrase: Verifying - Enter PEM pass phrase: $ openssl x509 -req -in certs/server_req.pem -extfile ./openssl_server.cnf \ -extensions v3_req -CA certs/rootca_cert.pem -CAkey private/rootcakey.pem \ -CAcreateserial -out certs/server_cert.pem Enter pass phrase for private/rootcakey.pem: $ cat certs/server_cert.pem certs/server_key.pem certs/rootca_cert.pem > certs /server.pem Code fragment 3.6:
Generate server private key and certicate
You can view the certicate the same way as the client's.
1
Once the pass phrase shouldn't be hard coded anymore, you could take two dierent ones 10
Chapter 4
Setting up the server 4.1 Compilation of the server service The server
service
should only be available on the servers which are used for running the ASIC
checks. The port the server is running on should
not
be specied during compilation: you can pass
this parameter when starting up the server from command line (see the
runasicserver
man
page). The compilation of the server service is, as for now, platform dependent: you should compile the service on the 64bit GNU/Linux server as on the 64bit HP-UX server. Before compilation, you should set the paths to the SSL certicates in the
SSLfunctions.h
SSLfunctions.cpp::init_context(). Also you should specify the location of the executioner executable in the ASICserver.h le, le and the pass phrase in
otherwise our service won't nd it when trying to execute commands. You can compile the server service by running:
1 2
$ cd ~guiasic/networklayer_source/src/ $ make -f Makefile.linux64 ASICserver Code fragment 4.1:
Compilation will result in executables named
Compile server service
runasicserver
and
executioner.
4.2 Execution of the server service For more information on starting the server service, you should read the man page of it. Default, we advise you to start it like this:
11
Karel Nijs
1 2
Automatisation of ASIC verication: Installation manual
$ cd ~guiasic/networklayer_source/src/ $ ./runasicserver 5001 Code fragment 4.2:
Start server service
This starts up the server service with SSL security and in silent mode: all logmessages will be suppressed, only error messages will be shown. If you're thinking about running the service as a daemon, the following would suit you:
1 2
$ cd ~guiasic/networklayer_source/src/ $ ./runasicserver 5001 -silent & Code fragment 4.3:
Start server service
Of course, rst test if the server is running ne as a
12
normal
process.
Chapter 5
Setting up the GUI (client) 5.1 Compilation of the client's shared object For the communication between the GUI and the (client side) network layer, we've developed a Tcl C extension, named
my_socket.so.
Attention! 1 This section, 5.1, has to be executed
, ever. This is because all the clients are running the same operating system. The servers do not support the Tix extension at this moment, so my_socket.so does not need to be recompiled on their platform. only once
SOCKETDIR for the /imec/other/guiasic/eindwerk/networklayer/
Before compilation, open the Makele and set the destination directory shared object. Default this would point t
Because this le is also compiled C++ code, you should compile it for your architecture rst, to use it:
1 2
$ cd ~guiasic/networklayer_source/src/ $ make -f Makefile.linux64 ASICclient
Compile client extension
Code fragment 5.1: This compilation results in the This object is
automatically
my_socket.so
shared object.
placed in the directory
SOCKETDIR,
specied in the Makele.
Before we can actually start the GUI, we also need to compile the
runasicgui
executable.
When starting this executable, we can run Bash commands from command line with the SUID bit set. Before compilation, you should set the path to the
runasicgui.cpp 1 2
scripts/verification.sh
source le.
$ cd ~guiasic/eindwerk/ $ g++ -Wall -o runasicgui runasicgui.cpp -DIMEC Code fragment 5.2:
Compile client executable 13
le in the
Karel Nijs
Automatisation of ASIC verication: Installation manual
After compilation you must set the permissions mentioned in Section 2.1. In the
scripts/verification.sh le, you should specify the name of the Tixwish executable
of your GNU/Linux system.
5.2 Execution of the GUI For more information on starting the GUI, you should read the man page of it.
14
Chapter 6
Application specic 6.1 Settings Most of the application settings are congurable using the
guiasic/config/application_settings.tcl These settings are valid for
all
le.
users using the application and can
not
be set for or by every
user individually. You can nd an example of the conguration le in Appendix C. The options which are not self explainatory are commented in the conguration le itself. There are two options users
can set
in a conguration le in their own home directory. The
options must be saved by using the Save Settings option in the application's View menu. The
turbo
option is not available for everyone because abuse may occur.
Users with more permissions may set the turbo option in their conguration le.
1 2 3
$ cat ~karel/.guiasic/settings.conf ::txtWorkingDir=/home/karel/ ::configfile::turbo=1 Code fragment 6.1:
It is
not
Personal conguration le
possible to set other Tcl variables the same way for security purposes. If you do want
::userSavedVariables eindwerk/config/application_settings.tcl
to do this, adjust the variable
in
6.2 Manual pages There are standard manual pages provided with this application. These manual pages are also accessible in HTML format from within the GUI.
15
Karel Nijs
Automatisation of ASIC verication: Installation manual
If you're interested in adjusting these pages, you can regenerate them with:
1 2 3
$ cd ~guiasic/eindwerk/man/7/ $ groff -man -Tascii runasicserver.7.man -Thtml > runasicserver.7.html $ groff -man -Tascii runasicgui.7.man -Thtml > runasicgui.7.html Code fragment 6.2:
Regenerating manual pages
6.3 Maintenance The Automatisation of ASIC verication application does not need
continuous
maintenance.
6.4 Global Every ve years the SSL certicates should be regenerated because the expire time is set to then. You may want to extend this time to seven, ten, . . . years in the OpenSSL conguration le(s). When new releases of the OpenSSL library are available and considered stable, you might want to upgrade them. On the other hand: if there aren't any
critical
releases, we advise you
to avoid constant recompilation. When updating to a new Tix version, you should specify the path to the executable in
scripts/verification.sh. Also the path to GNU GCC must be specied in the and
networklayer_source/src/Makefile.hpux
networklayer_source/src/Makefile.linux64
les.
6.5 Check execution The path to the Gscan executable must be set in
eindwerk/config/application_settings.tcl.
When updating to a new Calibre version, you should adjust the corresponding (soft) links,
eindwerk/scripts/calibre_linux_current.bash eindwerk/scripts/calibre_hpux_current.bash.
16
and
List of code fragments 2.1
Set directory permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2
Set
permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.3
Set toplevel directory permissions . . . . . . . . . . . . . . . . . . . . . . . . . .
4
runasicgui
3
2.5
eindwerk eindwerk
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
3.1
Setting up the CA environment . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
3.2
Creating a self-signed root certicate . . . . . . . . . . . . . . . . . . . . . . . .
8
3.3
Generate the client's private key
. . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.4
Generate client certicate
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.5
View client certicate
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.6
Generate server private key and certicate . . . . . . . . . . . . . . . . . . . . .
10
4.1
Compile server service
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
4.2
Start server service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
4.3
Start server service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
5.1
Compile client extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
5.2
Compile client executable
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
6.1
Personal conguration le
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
6.2
Regenerating manual pages
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
A.1
openssl_rootca.cnf
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
B.1
openssl_client.cnf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
C.1
application_settings.tcl
22
2.4
directory structure
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
directory structure
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
Appendix A
OpenSSL root CA conguration le 1 2
[ ca ] default_ca = defaultca
3 4 5 6 7 8 9 10
[ defaultca ] # specify defaults dir = /imec/other/guiasic/eindwerk/secure/ca # no trailing slash certificate = $dir/cacert.pem database = $dir/index.txt new_certs_dir = $dir/certs private_key = $dir/private/cakey.pem serial = $dir/serial
11 12 13 14
default_crl_days = 7 default_days = 1825 # days till certificate expire date (5 years) default_md = sha1
15 16 17
policy = defaultca_policy x509_extensions = cert_extensions
18 19 20 21 22 23 24 25 26
[ defaultca_policy ] # all fields are obligated commonName = supplied stateOrProvinceName = match countryName = match emailAddress = match organizationName = match organizationalUnitName = match
27 28 29
[ cert_extensions ] basicConstraints = CA:false
30
18
Karel Nijs
Automatisation of ASIC verication: Installation manual
31 32 33 34 35 36 37
[ req ] default_bits = 2048 # strong encryption = no problem, won't be used much default_keyfile = $dir/private/rootcakey.pem default_md = sha1 # no MD5 because of known weaknesses input_password = <password> output_password = <password>
38 39 40 41
prompt = no # use values specified below distinguished_name = root_ca x509_extensions = root_ca_extensions
42 43 44 45 46 47 48 49
[ root_ca ] commonName = rootCA stateOrProvinceName = Vlaams-Brabant countryName = BE # max TWO letters emailAddress = [email protected] organizationName = imec organizationalUnitName = europractice
50 51 52 53
[ root_ca_extensions ] basicConstraints = CA:true
# permit signing of certificates and CRLs
Code fragment A.1:
19
openssl_rootca.cnf
Appendix B
OpenSSL client conguration le 1 2
default_days = 1825 default_md = sha1
# days till certificate expire date (5 years)
3 4 5 6 7 8 9 10 11
[ req ] default_bits = 512 # weak encryption, certificate will be used a lot distinguished_name = client prompt = no req_extensions = v3_req #input_password = "" #output_password = "" attributes = req_attributes
12 13 14 15 16
[ req_attributes ] #challengePassword #challengePassword_min #challengePassword_max
= A challenge password = 0 = 20
17 18 19 20 21 22 23 24 25
[ client ] commonName = client stateOrProvinceName = Vlaams-Brabant countryName = BE # max TWO letters emailAddress = [email protected] organizationName = imec organizationalUnitName = europractice
26 27 28 29 30
[ v3_req ] basicConstraints = critical,CA:FALSE # keyUsage = nonRepudiation, digitalSignature, keyEncipherment,
20
Karel Nijs
31
Automatisation of ASIC verication: Installation manual
dataEncipherment, keyAgreement # extendedKeyUsage=emailProtection,clientAuth Code fragment B.1:
21
openssl_client.cnf
Appendix C
Application conguration le 1 2
# directory containing all the rules files set ::basedir "/imec/other/guiasic/EUROPRACTICE/"
3 4 5
# path to the configuration file set ::configfile [file join $::progroot "config" "verification.conf"]
6 7 8
# path to the USER configuration file set ::userconfigfile [file join $::env(HOME) ".guiasic" "settings.conf"]
9 10 11
# application title set ::apptitle "Automatisation of ASIC verification"
12 13
14
# server port (this should be the same as the port you started the server service with) set ::serverport 5001
15 16 17 18 19
# offline modues # 0: query the servers for their information DEFAULT # 1: do NOT contact servers when loading config file set ::offline 0
20 21 22
# default text editor for editing the rules files set ::editor "nedit"
23 24 25
# default browser for opening the man pages (html) set ::browser "mozilla"
26 27 28
# script for monitoring server activity set ::moniscript [file join $::progroot "scripts" "server_monitor.sh"]
29
22
Karel Nijs
30 31
Automatisation of ASIC verication: Installation manual
# same name as tclNAME variable in my_socket.ccp set ::nwservice "::nw_service::my_socket"
32 33 34 35 36
# security type used # plain: use plain text security (= none!) # ssl: use ssl security DEFAULT set ::securityType "ssl"
37 38 39 40 41
# should the GUI suppress log and error messages? # 1: be silent DEFAULT # 0: show messages set ::silent 1
42 43 44
45 46 47
# should the network layer be silent too? #@note setting this to 0 (not silent) will generate a LOT messages, so you shouldn't # 1: be silent DEFAULT # 0: show messages set ::silentNetworkLayer 1
48 49 50
# directory which contains all the images set ::picsdir [file join $::progroot "PICS"]
51 52 53
# default permissions for created files and directories set ::fileperms "rwxr-xr--"
54 55 56
# the path to the command used for gscan set ::gscan::cmd "/imec/software/gdsplot/v535a/linux/bin/gscan";
57 58 59 60 61
62
# FORBIDDEN PATHS # @note specify all the forbidden paths in a list here # (a path like /imec/otherguiasic/eindwerk/secure (and all below) is forbidden) set ::forbiddenPaths [list "/imec/other/guiasic/eindwerk/secure"] Code fragment C.1:
application_settings.tcl
23
Bibliography [1] P. C. John Viega, Matt Messier.
Network Security with OpenSSL.
Inc., 2002. ISBN 0-596-00270-X.
24
O'Reilly & Associates
B¼lage D
Rapporten D.1 Calibre
152
Karel Nijs
1 2 3 4 5 6
7 8 9
Automatisatie van ASIC vericatie
================================================================================ === CALIBRE::DRC-H SUMMARY REPORT === Execution Date/Time: Wed May 3 17:20:38 2006 Calibre Version: v2005.3_12.18 Mon Oct 24 16:29:54 PDT 2005 Rule File Pathname: /imec/other/umc25/tmp/DRC*/ G-DF-LOGIC18-1.8V-3.3V-1P3M-4M-5M-6M-Calibre-drc-2.7-P1.txt Rule File Title: amis > 0.7um > C05M-D_3M_1P > DRC* (hier) Layout Primary Cell: AMCHIP Excluded Cells:
10 11 12 13 14 15 16
---------------------------------------------------------------------------------- RUNTIME WARNINGS --WARNING : Check the .sum file for acute angles
17 18 19 20 21 22 23 24 25
---------------------------------------------------------------------------------- ERROR SPECIFICATIONS --RULECHECK 4.1H ................... TOTAL Result Count = 4 (4) Minimum DIFFUSION density over 500um x 500 um areas is 20% -----------------------------------------------------------------------
26 27 28 29
RULECHECK 4.13G .................. TOTAL Result Count = 1 (1) The Metal1 coverage must be larger than 25% for every 500*500um square -----------------------------------------------------------------------
30 31 32 33
RULECHECK 4.15F .................. TOTAL Result Count = 1 (1) The Metal2 coverage must be larger than 30% of entire chip area -----------------------------------------------------------------------
34 35 36 37
RULECHECK 4.15G .................. TOTAL Result Count = 1 (1) The Metal2 coverage must be larger than 25% for every 500*500um square -----------------------------------------------------------------------
38 39 40 41
RULECHECK 4.17F .................. TOTAL Result Count = 1 (1) The Metal3 coverage must be larger than 30% of entire chip area -----------------------------------------------------------------------
42 43 44 45
RULECHECK 4.17G .................. TOTAL Result Count = 1 (1) The Metal3 coverage must be larger than 25% for every 500*500um square -----------------------------------------------------------------------
153
Karel Nijs
Automatisatie van ASIC vericatie
46 47 48 49
RULECHECK 4.19F .................. TOTAL Result Count = 1 (1) The Metal4 coverage must be larger than 30% of entire chip area -----------------------------------------------------------------------
50 51 52 53
RULECHECK 4.19G .................. TOTAL Result Count = 1 (1) The Metal4 coverage must be larger than 25% for every 500*500um square -----------------------------------------------------------------------
54 55 56 57
RULECHECK 4.21F .................. TOTAL Result Count = 1 (1) The Metal5 coverage must be larger than 30% of entire chip area -----------------------------------------------------------------------
58 59 60 61
RULECHECK 4.21G .................. TOTAL Result Count = 1 (1) The Metal5 coverage must be larger than 25% for every 500*500um square -----------------------------------------------------------------------
62 63 64 65
RULECHECK 4.23E .................. TOTAL Result Count = 1 (1) The Metal6 coverage must be larger than 30% of entire chip area -----------------------------------------------------------------------
66 67 68 69
RULECHECK 4.23F .................. TOTAL Result Count = 1 (1) The Metal6 coverage must be larger than 25% for every 500*500um square -----------------------------------------------------------------------
70 71 72 73 74 75 76 77 78 79
---------------------------------------------------------------------------------- SUMMARY --TOTAL CPU Time: 8353 TOTAL REAL Time: 4465 TOTAL Original Layer Geometries: 6770282 (174968328) TOTAL DRC RuleChecks Executed: 461 TOTAL DRC Results Generated: 54 (54) Codefragment D.1:
Ingekort Calibre rapport
154
Karel Nijs
Automatisatie van ASIC vericatie
D.2 Dracula
155
Karel Nijs
1 2 3 4 5
6 7 8
9 10 11 12 13
Automatisatie van ASIC vericatie
================================================================================ === DRACULA::DRC SUMMARY REPORT === Execution Date/Time: 2006-05-09_00u57 Rule File Pathname: /home/karel/eindwerk_CVS/eindwerk/scripts+ config_HUIDIG/dracula/dracjob_Erwin_2006-04/dracjob.erc Rule File Title: austriamicrosystems > 0.8um > CXQ_2M_2P_HR > DRC Layout System: GDS Layout Path(s): /home/karel/eindwerk_CVS/eindwerk/scripts+ config_HUIDIG/calibre/rules_test/design/GVdP_ADC018_June05.gds Layout Primary Cell: UMRFCHIP24 Current Directory: /home/karel/eindwerk_CVS/workingdir/ User Name: karel Keep Data: NO --------------------------------------------------------------------------------
14 15 16 17 18 19
Listing of Violations: --------------------------WPPPUS45 : INFO** Unsalicided P_PLUS resistor
20 21
BONDPAD45 : INFO** all your bondpads
22 23
PCK145 : Node with no path to power
24 25
PCK245 : Node with no path to ground
26 27
PCK445 : Node with no path to power nor ground
28 29
FLMOS45 : FLoating MOS terminal
30 31
FLOAT45 : FLoating conductor nodes
32 33
PTIEDP45 : PMOS with gate to POWER
34 35
NTIEDP45 : NMOS with gate to POWER
36 37
PTIEDG45 : PMOS with gate to GROUND
38 39
NTIEDG45 : NMOS with gate to GROUND
40 41
PSDTIEG45 : PMOS with drain to GROUND
42 43
NSDTIEP45 : NMOS with drain to POWER
44
156
Karel Nijs
45
Automatisatie van ASIC vericatie
FLWEL45 : NWELL not connected to VDD. HIPORES wells are not shown !
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
Error Cell __________ WPPPUS45 PCK145 PCK245 FLMOS45 PTIEDP45 NTIEDP45 PTIEDG45 NTIEDG45 PSDTIEG45 NSDTIEP45 FLWEL45
Polygon Count _____________ 185 112.05 29196 7.24 151 2013.77 200 1189.38 38992 71.20 70702 44.11 237721 128.75 525180 136.67 193000 255.09 70537 7.48 272 109.00
Error Boundaries ________________ 112.05 4729.95 7.24 4834.76 3046.65 4128.32 1531.08 4128.32 71.20 4770.80 44.11 4797.89 128.75 4713.25 136.67 4705.33 280.74 4627.25 7.48 4834.52 111.65 4733.00
63 64 65 66
---- end of report file ---Codefragment D.2:
157
Dracula rapport
4729.95 4834.76 4169.06 4560.57 4770.80 4797.89 4713.25 4705.33 4563.66 4834.52 4733.00
Bibliograe [1] V. Authors. Unix 0-679-79073-X.
Power Tools. O'Reilly & Associates Inc., 1st ed. edition, 1993. ISBN
[2] V. Authors. The cybervote project. Technical report, K.U. Leuven Research & Development, 2002. http://www.eucybervote.org/Reports/MSI-WP2-D7V1-V1.0.htm. [3] J. L. Brian Hatch. 0-07-222742-7.
Hacking Linux Exposed. McGraw-Hill, 2d ed. edition, 2002. ISBN
[4] C. Flynt. Practical Programming in edition, 2003. ISBN 1-55860-802-8.
Tcl and Tk. Morgen Kaufmann Publishers, 2nd ed.
[5] G. V. Hoogenbemt. Beveiliging. [email protected].
Hogeschool
Gent,
dep.
INWE,
2004.
[6] G. V. Hoogenbemt. Objectgeoriënteerd Programmeren, chapter 14 Exception handling. Hogeschool Gent, dep. INWE, 2005. [email protected]. [7] P. C. John Viega, Matt Messier. Inc., 2002. ISBN 0-596-00270-X. [8] G. Laan. 1084-9.
Network Security with OpenSSL. O'Reilly & Associates
Aan de slag met C++. Academic Service, 3rd ed. edition, 1998. ISBN 90-395-
[9] G. Lequex. Een introductie tot het zetsysteem, LATEX. Zeus Werkgroep Informatica, Universiteit Gent, 2003. http://zeus.hogent.be/ gaspard/latex. [10] J. V. Meirvenne. Netwerkprogrammatie. [email protected].
Hogeschool Gent, dep. INWE, 2004.
[11] V. Metcalfe and A. Gierth. Programming UNIX Sockets ftp://rtfm.mit.edu/pub/usenet/news.answers/unix-faq/socket. [12] J. K. Ousterhout. [13] I. RedBook.
Joa-
in C - FAQ, 1998.
Tcl and the Tk Toolkit. Addison-Wesley, 1994. ISBN 0-201-63337-X.
TCP/IP Tutorial and Technical Overview, 2001.
158
Karel Nijs
Automatisatie van ASIC vericatie
[14] W. Stevens. UNIX 0-13-490012-X. [15] W. R. Stevens. 020163354X.
Network Programming. Prentice-Hall Int., 2nd ed. edition, 1997. ISBN
TCP/IP Illustrated Volume 2. Addison-Wesley, 1st ed. edition, 1995. ISBN
[16] D. T. Welsh Matt, Dalheimer Matthias Kalle. 4th ed. edition, 2003. ISBN 0-596-00272-6.
159
Running LINUX. O'Reilly & Associates Inc.,