- Jak zjistit, co na našem pc po spuštění běží
- spustím, jen to, co se ověří podle podpisu
- BIOS ověří MBR
- MBR ověří GRUB
- …
RESET: PCR = 0
MEASURE: PCR = H(PCR|H(MBR)
MEASURE: PCR = H(PCR|H(GRUB)
- …
- Hodnota PCR musí být chráněna (jinak si malware PCR přepíše)
- Hodnota PCR může být podepsána (důkaz, že PCR nabyl danou hodnotu)
https://github.com/petrs/TPM_PCR
- robotanik - https://www.umimeprogramovat.cz/robotanik
- funkce volá sebe sama
- každé zalvání funkce si vytvoří rámec na zásobníku
- Funkční volání vyžaduje režii (pameť a CPU)
- předání argumentů, předání návratové hodnoty, úklid zásobníku, …
- při opakovaném hlubokém zanoření výrazné
- Lze přepsat do nerekurzivního tvaru
- Využití zásobníku volání (call stack)
- Kód z knihovny je přímo zahrnut do kódu aplikace
- nevyžaduje jiné soubory ke spuštění
- duplicitní kód
- přeložený kód knihovny je v samostatném soubory, aplikace jen volá funkce
- knihovna se nahrává implicitně při spuštění programu
- knihovna se nahrává explicitně v kódu
- statické linkování - probíhá během překladu (kód knihovny je začleněn do kódu aplikace)
- dynamické linkování - probíhá za běhu aplikace (v době překladu nemusí být kód znám)
- statucké linkování sdílených knihoven
- aplikace očekává přítomnost externích souborů se spustitelným kódem knihovních funkcí
- Windows:
library.dll, Unix: library.so
- Dynamické nahrávání sdílených knihoven
- aplikace sama otevírá externí soubor se spustitelným kódem knihovních funkcí
- windows:
LoadLibrary(), GetProcAddress(), FreeLibrary()
- Unix:
dlopen(), dlsym(), dlclose()
- Preferujeme funkce ze standarní knihovny (snadno přístupné a přenositelné)
- Vyváženost použité vs nepoužité funkčnosti
- OpenSSL pouze pro výpočet SHA2-256 je zbytečná
- Preferujeme knihovnu s abstrakcí odpovídající našim požadavkům
- Preferujeme menší počet použitých knihoven
- každá knihovna má vlastní syp API -> dopad na čitelnost kódu
- Pro malou konkrétní úlohu může být nejsnažší vyjmout a upravit kód
- BSD-like, MIT, public domain
- můžeme použít téměř libovolně, uvést jméno autora
- GPL, Lesser-GPL
- pokud použijeme, musíme zveřejnit i naše upravené zdrojové kódy
- Proprietární licence
- dle podmínek licence, typicky není nutné zveřejnit náš kód
- Duální licencování
- kód typicky dostupný jako open source (např. GPL), při poplatku jako prorietání licence
- https://en.wikipedia.org/wiki/Comparison_of_free_and_open-source_software_licences
- https://choosealicense.com/
- 24 hlavičkových souborů - https://en.wikipedia.org/wiki/C_standard_library
- https://en.wikipedia.org/wiki/Limits.h
- Potřebné pro kontrolu rozsahů hondot primitivních datových typů
- na různých platformách se mohou lišit
CHAR_BIT - počet bitů v jednom char
- typicky 8 bitů, ale může mít 16 bitů a víc
- rozdíl mezi 32/64
- ascii kód znaky
- pro široké znaky
<wctype.h>
- obsahuje funkce pro práci z řetězci
- Navíc rychlé funkce pro pro práci s pamětí
void *memset(void *, int c, size_t n);
- nastaví zadanou oblast paměti na znak
c
void *memcpy(void *dest, const void *src, size_t n);
- zkopíruje ze src do dest
n bajtů
int memcmp(const void *s1, const void *s2, size_t n);
- porovnává bloky paměti na bajtové úrovni
- pracují na úrovní bajtů - potřeba nejdříve spočítat velikost
- Funkce pro získávání času
time() - počet sekund od 00:00, 1. ledna, 1970 UTC
clock() - “tiky” od začátku běhu programu (obvykle ms
- funkce pro konverzi času (sekundy -> struct tm)
- formátování času a výpis
ctime() - lidsky čitelný formát, lokální čas
asctime() - lidsky čitelný řetězec, UTC
strftime() - formátování do řetězce dle masky
time() vrací naměřený čas s přesností 1 sekundy (není vhodné na přesné měření délky operací)
- přesnější měření možné pomocí funkce
clock()
- vrátí počet “tiků” od startu programu
- makro
CLOCKS_PER_SEC definuje počt tiků za sekundu
- Pro krátké operace to většinou nestačí
- lze řešit provedením opeace v cyklu s velkým množství iterací
- Pozor na optimalizace překladače
- chceme měřit rychlost v Release režimu
- některé části kódu mohou být zcela odstraněny (nepoužité proměnné) nebo vyhodnoceny při překladu (konstanty)
- Pozor na vliv ostaních komponent (cache, …)
- Funkce pro konverzi typů z řetězce do čísla (
atoi, atof, …)
- Generování pseudonáhodných sekvencí
- deterministická sekvence čísel z počátečního semínka
srand() - nastavení semínka
int rand(void); - další náhodné číslo v sekvenci (od 0 do RAND_MAX)
- Není vhodné pro kryptografické použítí!! (generování hesel, …)
- Funkce pro spuštění a kontrolu procesů
int system(const char *command); - vykoná externí příkaz
char *getenv(const char *name);
- standardní knihovna obsahuje řadící a vyhledávací funkci
- quicksort - řadí posloupnost prvků v poli
- rychlé vyhledávání v seřazeném poli (půlení intervalů)
void qsort(void *base, size_t n, size_t sz, int (*cmp) (const void*, const void*));
void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*cmp) (const void *, const void *));
- konstanty -
M_PI, M_SQRT2, M_E, …
- mat funkce -
sin, cos, pow
- zaokrouhlovací funkce
- od C99 další rozšíření -
trunc, fmax, fmin
- rozšíření návratového typu až na
long long (llround)
gcc hello.c -lm
- Defacto nejnovější verze je C17 (2017, odstraňuje defekty C11)
- http://en.wikipedia.org/wiki/C11_(C_standard_revision)
- http://www.jauu.net/talks/data/c1x.pdf
#include <threads.h>
- Velmi podobné vláknům v POSIXu
pthread_create -> thr_create
pthread_mutex_init -> mtx_init
- Specifikace lokální proměnné ve vlákně
_Thread_local
- lokální proměnná ve funkci spuštěné paralelně v několika vláknech
_Thread_local storage-class
_Atomic typ qualifier, <stdatomic.h>
- Metody pro synchronizaci
- Atomické operace
_Atomic int foo;
atomic_{load,store,exchange}
atomic_fetch_{add,sb,or,xor,and}
atomic_compare_exchange_
- Vyhodnocení makra v závilosti na typu proměnné (Type-generic expressions)
- klíčové slovo
_Generic
#define FOO(X) myfoo(X)
#define FOO(X)
_Generic((X), long: fool, char: fooc, default foo) (X)