Jak mogę zaszyfrować bajty za pomocą modułu TPM komputera?
CryptProtectData
Windows zapewnia (stosunkowo) proste API do szyfrowania obiektu blob za pomocą CryptProtectData
API, które możemy opakować w łatwą w użyciu funkcję:
public Byte[] ProtectBytes(Byte[] plaintext)
{
//...
}
Szczegóły ProtectBytes
są mniej ważne niż pomysł, że możesz z niego dość łatwo korzystać:
- oto bajty, które chcę zaszyfrować tajnym kluczem przechowywanym w
System
- oddaj mi zaszyfrowany obiekt blob
Zwrócony obiekt BLOB to nieudokumentowana struktura dokumentacji , która zawiera wszystko, co jest potrzebne do odszyfrowania i zwrócenia oryginalnych danych (algorytm skrótu, algorytm szyfrujący, sól, podpis HMAC itp.).
Dla kompletności, oto przykładowa implementacja pseudokodu, ProtectBytes
która używa Crypt API
do ochrony bajtów:
public Byte[] ProtectBytes(Byte[] plaintext)
{
//Setup our n-byte plaintext blob
DATA_BLOB dataIn;
dataIn.cbData = plaintext.Length;
dataIn.pbData = Addr(plaintext[0]);
DATA_BLOB dataOut;
//dataOut = EncryptedFormOf(dataIn)
BOOL bRes = CryptProtectData(
dataIn,
null, //data description (optional PWideChar)
null, //optional entropy (PDATA_BLOB)
null, //reserved
null, //prompt struct
CRYPTPROTECT_UI_FORBIDDEN || CRYPTPROTECT_LOCAL_MACHINE,
ref dataOut);
if (!bRes) then
{
DWORD le = GetLastError();
throw new Win32Error(le, "Error calling CryptProtectData");
}
//Copy ciphertext from dataOut blob into an actual array
bytes[] result;
SetLength(result, dataOut.cbData);
CopyMemory(dataOut.pbData, Addr(result[0]), dataOut.cbData);
//When you have finished using the DATA_BLOB structure, free its pbData member by calling the LocalFree function
LocalFree(HANDLE(dataOut.pbData)); //LocalFree takes a handle, not a pointer. But that's what the SDK says.
}
Jak zrobić to samo z TPM?
Powyższy kod jest przydatny do szyfrowania danych tylko dla lokalnego komputera. Dane są szyfrowane przy użyciu System
konta jako generatora kluczy ( szczegóły, choć interesujące, są nieważne ). W rezultacie mogę zaszyfrować dane (np. Klucz główny szyfrowania dysku twardego), które mogą być odszyfrowane tylko przez maszynę lokalną.
Nadszedł czas, aby pójść o krok dalej. Chcę zaszyfrować niektóre dane (np. Klucz główny szyfrowania dysku twardego), które mogą być odszyfrowane tylko przez lokalny moduł TPM. Innymi słowy, chcę zamienić Qualcomm Trusted Execution Environment ( TEE ) na poniższym schemacie blokowym na Androida, na TPM w Windows:
Uwaga : zdaję sobie sprawę, że moduł TPM nie wykonuje podpisywania danych (a jeśli tak, to nie gwarantuje, że podpisywanie tych samych danych za każdym razem da te same dane binarne). Dlatego byłbym skłonny zastąpić „RSA podpisywanie” z „blob szyfrowania 256-bitowego sprzętowego związany z kluczem” .
Więc gdzie jest kod?
Problem polega na tym, że programowanie TPM jest całkowicie nieudokumentowane w MSDN . Nie ma dostępnego API do wykonywania jakichkolwiek operacji. Zamiast tego musisz znaleźć kopię stosu oprogramowania Trusted Computing Group (aka TSS) , dowiedzieć się, jakie polecenia wysłać do TPM wraz z ładunkami, w jakiej kolejności i wywołać funkcję Tbsip_Submit_Command systemu Windows, aby bezpośrednio przesłać polecenia:
TBS_RESULT Tbsip_Submit_Command(
_In_ TBS_HCONTEXT hContext,
_In_ TBS_COMMAND_LOCALITY Locality,
_In_ TBS_COMMAND_PRIORITY Priority,
_In_ const PCBYTE *pabCommand,
_In_ UINT32 cbCommand,
_Out_ PBYTE *pabResult,
_Inout_ UINT32 *pcbOutput
);
System Windows nie ma interfejsu API wyższego poziomu do wykonywania działań.
Jest to moralny odpowiednik próby utworzenia pliku tekstowego przez wydanie poleceń SATA I / O na dysk twardy .
Dlaczego nie po prostu użyć spodni
Trusted Computing Group (TCG) zdefiniowała swój własny interfejs API: TCB Software Stack (TSS) . Implementacja tego API została stworzona przez kilka osób i nazywa się TrouSerS . Facet następnie przeportował ten projekt do Windows .
Problem z tym kodem polega na tym, że nie można go przenieść do świata Windows. Na przykład nie możesz go używać z Delphi, nie możesz go używać z C #. To wymaga:
- OpenSSL
- p Wątek
Chcę tylko, aby kod zaszyfrował coś za pomocą mojego modułu TPM.
Powyższe CryptProtectData
nie wymaga niczego innego niż to, co znajduje się w treści funkcji.
Jaki jest równoważny kod do szyfrowania danych przy użyciu modułu TPM? Jak zauważyli inni, prawdopodobnie będziesz musiał zapoznać się z trzema podręcznikami TPM i samodzielnie skonstruować obiekty blob . Prawdopodobnie wiąże się to z TPM_seal
poleceniem. Chociaż myślę, że nie chcę zapieczętowywać danych, myślę, że chcę to powiązać :
Wiązanie - szyfruje dane przy użyciu klucza powiązania TPM, unikalnego klucza RSA pochodzącego z klucza magazynu. Pieczętowanie - szyfruje dane w sposób podobny do wiązania, ale dodatkowo określa stan, w jakim musi znajdować się TPM, aby dane mogły zostać odszyfrowane (niezapieczętowane)
Próbuję przeczytać trzy wymagane tomy, aby znaleźć 20 linii kodu, których potrzebuję:
Ale nie mam żadnego pojęcia, co czytam. Gdyby był jakiś samouczek lub przykłady, mógłbym spróbować. Ale jestem kompletnie zagubiony.
Dlatego prosimy o Stackoverflow
W ten sam sposób mogłem zapewnić:
Byte[] ProtectBytes_Crypt(Byte[] plaintext)
{
//...
CryptProtectData(...);
//...
}
czy ktoś może podać odpowiedni odpowiednik:
Byte[] ProtectBytes_TPM(Byte[] plaintext)
{
//...
Tbsip_Submit_Command(...);
Tbsip_Submit_Command(...);
Tbsip_Submit_Command(...);
//...snip...
Tbsip_Submit_Command(...);
//...
}
robi to samo, z wyjątkiem tego, że klucz zamknięty w System
LSA jest zablokowany w TPM?
Początek badań
Nie wiem dokładnie, co oznacza wiązanie . Ale patrząc na TPM Main - Part 3 Commands - Specification Version 1.2, jest wzmianka o bind :
10.3 TPM_UnBind
TPM_UnBind pobiera obiekt BLOB danych będący wynikiem polecenia Tspi_Data_Bind i odszyfrowuje go w celu wyeksportowania do użytkownika. Wzywający musi autoryzować użycie klucza, który odszyfruje przychodzący obiekt BLOB. TPM_UnBind działa na zasadzie blok po bloku i nie ma pojęcia o jakiejkolwiek relacji między jednym blokiem a drugim.
Co jest mylące jest tam jest brak Tspi_Data_Bind
poleceń.
Wysiłek badawczy
Przerażające jest to, że nikt nigdy nie zadał sobie trudu, aby udokumentować TPM lub jego działanie. To tak, jakby spędzali cały swój czas na wymyślaniu tej fajnej rzeczy do zabawy, ale nie chcieli radzić sobie z bolesnym krokiem, aby uczynić ją użyteczną do czegoś.
Począwszy od (teraz) bezpłatnej książki Praktyczny przewodnik po TPM 2.0: Korzystanie z modułu zaufanej platformy w nowej erze bezpieczeństwa :
Rozdział 3 - Krótki samouczek dotyczący TPM 2.0
Moduł TPM ma dostęp do samodzielnie wygenerowanego klucza prywatnego, dzięki czemu może szyfrować klucze za pomocą klucza publicznego, a następnie przechowywać wynikowy obiekt blob na dysku twardym. W ten sposób moduł TPM może przechowywać praktycznie nieograniczoną liczbę kluczy dostępnych do użytku, ale nie marnuje cennej pamięci wewnętrznej. Klucze przechowywane na dysku twardym można wymazać, ale można je również zarchiwizować, co projektantom wydawało się akceptowalnym kompromisem.
Jak zaszyfrować klucz kluczem publicznym modułu TPM?
Rozdział 4 - Istniejące aplikacje korzystające z modułów TPM
Aplikacje, które powinny używać modułu TPM, ale tego nie robią
W ciągu ostatnich kilku lat wzrosła liczba aplikacji internetowych. Wśród nich są internetowe kopie zapasowe i przechowywanie. Obecnie wiele firm oferuje takie usługi, ale o ile nam wiadomo, żaden z klientów tych usług nie pozwala użytkownikowi zablokować klucza usługi kopii zapasowej w module TPM. Gdyby to zostało zrobione, z pewnością byłoby miło, gdyby sam klucz TPM został zarchiwizowany, kopiując go na wielu komputerach. Wydaje się, że jest to szansa dla programistów.
W jaki sposób programista blokuje klucz w module TPM?
Rozdział 9 - Heirarchie
PRZYPADEK: PRZECHOWYWANIE HASŁA DO LOGOWANIA
Typowy plik haseł przechowuje zasolone skróty haseł. Weryfikacja polega na zasoleniu i zahaszowaniu podanego hasła i porównaniu go z zapisaną wartością. Ponieważ obliczenie nie obejmuje hasła, podlega atakowi offline na plik z hasłami.
W tym przypadku użycia jest używany klucz HMAC wygenerowany przez moduł TPM. Plik haseł przechowuje HMAC solonego hasła. Weryfikacja polega na soleniu i HMAC podanego hasła i porównaniu go z przechowywaną wartością. Ponieważ osoba atakująca w trybie offline nie ma klucza HMAC, osoba atakująca nie może zamontować ataku, wykonując obliczenia.
To mogłoby zadziałać. Jeśli moduł TPM ma tajny klucz HMAC i tylko mój moduł TPM zna klucz HMAC, mogę zastąpić „Podpisz (inaczej szyfrowanie TPM kluczem prywatnym)” na „HMAC”. Ale w następnej linii całkowicie się odwraca:
TPM2_Create, określając klucz HMAC
Nie jest tajemnicą TPM, jeśli muszę określić klucz HMAC. Fakt, że klucz HMAC nie jest tajny, ma sens, gdy zdasz sobie sprawę, że jest to rozdział o narzędziach kryptograficznych, które zapewnia moduł TPM. Zamiast samodzielnie pisać SHA2, AES, HMAC lub RSA, możesz ponownie wykorzystać to, co już jest w module TPM.
Rozdział 10 - Klucze
Największą zaletą modułu TPM jest zdolność aplikacji do używania kluczy przy jednoczesnym zachowaniu ich bezpieczeństwa w urządzeniu jako urządzenie zabezpieczające . Moduł TPM może zarówno generować, jak i importować klucze generowane zewnętrznie. Obsługuje klucze asymetryczne i symetryczne.
Doskonały! Jak ty to robisz!?
Generator kluczy
Prawdopodobnie największą siłą TPM jest jego zdolność do generowania klucza kryptograficznego i ochrony jego sekretu w granicach sprzętowych. Generator kluczy jest oparty na własnym generatorze liczb losowych TPM i nie polega na zewnętrznych źródłach losowości. W ten sposób eliminuje słabości oparte na słabym oprogramowaniu z niewystarczającym źródłem entropii.
Czy moduł TPM ma możliwość generowania kluczy kryptograficznych i ochrony swoich danych tajnych w granicach sprzętowych? Czy tak, jak?
Rozdział 12 - Rejestry konfiguracji platformy
PCR do autoryzacji
PRZYKŁAD UŻYCIA: USZCZELNIANIE KLUCZA SZYFROWANIA TWARDEGO DYSKU DO STANU PLATFORMY
Aplikacje szyfrujące na całym dysku są znacznie bezpieczniejsze, jeśli moduł TPM chroni klucz szyfrujący, niż gdyby był przechowywany na tym samym dysku, chronionym tylko hasłem. Po pierwsze, sprzęt TPM ma ochronę przed włamaniem (patrz rozdział 8, aby zapoznać się ze szczegółowym opisem ochrony przed atakiem słownikowym TPM), co sprawia, że atak siłowy na hasło jest niepraktyczny. Klucz chroniony tylko przez oprogramowanie jest znacznie bardziej podatny na słabe hasło. Po drugie, klucz programowy przechowywany na dysku jest znacznie łatwiejszy do kradzieży. Weź dysk (lub kopię zapasową dysku), a otrzymasz klucz. Gdy moduł TPM przechowuje klucz, cała platforma lub przynajmniej dysk i płyta główna muszą zostać skradzione.
Plombowanie umożliwia ochronę klucza nie tylko hasłem, ale także polityką. Typowa polityka blokuje klucz do wartości PCR (stanu oprogramowania) aktualnych w czasie uszczelniania. Zakłada się, że stan przy pierwszym uruchomieniu nie jest zagrożony. Każde preinstalowane złośliwe oprogramowanie obecne przy pierwszym uruchomieniu zostanie zmierzone w PCR, a tym samym klucz zostanie zapieczętowany do stanu zhakowanego oprogramowania. Mniej ufne przedsiębiorstwo może mieć standardowy obraz dysku i pieczęć do PCR reprezentujących ten obraz. Te wartości PCR byłyby wstępnie obliczane na prawdopodobnie bardziej zaufanej platformie. Jeszcze bardziej wyrafinowane przedsiębiorstwo użyłoby TPM2_PolicyAuthorize i dostarczyło kilka biletów autoryzujących zestaw zaufanych wartości PCR. W rozdziale 14 znajduje się szczegółowy opis autoryzacji polityki i jej zastosowania do rozwiązania problemu kruchości PCR.
Chociaż hasło może również chronić klucz, bezpieczeństwo jest większe nawet bez hasła klucza TPM. Osoba atakująca mogła uruchomić platformę bez podania hasła TPMkey, ale nie mogła się zalogować bez nazwy użytkownika i hasła systemu operacyjnego. OSsecurity chroni dane. Osoba atakująca może uruchomić alternatywny system operacyjny, powiedzmy z Live DVD lub pendrive'a zamiast z dysku twardego, aby ominąć zabezpieczenie logowania do systemu operacyjnego. Jednak ta inna konfiguracja rozruchu i oprogramowanie zmieniłyby wartości PCR. Ponieważ te nowe reakcje PCR nie byłyby zgodne z zapieczętowanymi wartościami, moduł TPM nie zwolniłby klucza odszyfrowywania, a dysk twardy nie mógł zostać odszyfrowany.
Doskonały! Tak się składa, że właśnie o to mi chodzi. Jest to również przypadek użycia, do którego Microsoft używa modułu TPM. Jak mam to zrobić!?
Przeczytałem więc całą książkę i nie znalazłem w niej niczego użytecznego. Co robi wrażenie, bo liczy 375 stron. Zastanawiasz się, co zawierała ta książka - i patrząc wstecz, nie mam pojęcia.
Rezygnujemy więc z ostatecznego przewodnika po programowaniu TPM i zamiast tego zwracamy się do dokumentacji firmy Microsoft:
Z zestawu narzędzi Microsoft TPM Platform Crypto-Provider Toolkit . Wskazuje dokładnie, co chcę zrobić:
Klucz poręczenia lub EK
EK ma na celu zapewnienie wiarygodnego identyfikatora kryptograficznego platformy. Przedsiębiorstwo może utrzymywać bazę danych kluczy poparcia należących do modułów TPM wszystkich komputerów w przedsiębiorstwie lub kontroler sieci szkieletowej centrum danych może mieć bazę danych modułów TPM we wszystkich modułach blade. W systemie Windows możesz użyć dostawcy NCrypt opisanego w sekcji „Platform Crypto Provider in Windows 8”, aby odczytać publiczną część EK.
Gdzieś w module TPM znajduje się klucz prywatny RSA. Ten klucz jest tam zamknięty - nigdy go nie widzi świat zewnętrzny. Chcę, aby moduł TPM podpisał coś swoim kluczem prywatnym (tj. Zaszyfrował to swoim kluczem prywatnym).
Chcę więc najbardziej podstawowej operacji, jaka może istnieć:
Zaszyfruj coś swoim kluczem prywatnym. Nie proszę nawet (jeszcze) o bardziej skomplikowane rzeczy:
- „uszczelnianie” go na podstawie stanu PCR
- tworzenie klucza i przechowywanie go w pamięci ulotnej lub nieulotnej
- tworzenie klucza symetrycznego i próba załadowania go do modułu TPM
Proszę o najbardziej podstawową operację, jaką może wykonać TPM. Dlaczego nie można uzyskać informacji o tym, jak to zrobić?
Mogę uzyskać losowe dane
Wydaje mi się, że byłem bezczelny, kiedy powiedziałem, że podpisywanie RSA jest najbardziej podstawową rzeczą, jaką może zrobić TPM. Najbardziej podstawową rzeczą TPM może zostać poproszony zrobić, to dać mi losowych bajtów. Że nauczyłem się, jak to zrobić:
public Byte[] GetRandomBytesTPM(int desiredBytes)
{
//The maximum random number size is limited to 4,096 bytes per call
Byte[] result = new Byte[desiredBytes];
BCRYPT_ALG_HANDLE hAlgorithm;
BCryptOpenAlgorithmProvider(
out hAlgorithm,
BCRYPT_RNG_ALGORITHM, //AlgorithmID: "RNG"
MS_PLATFORM_CRYPTO_PROVIDER, //Implementation: "Microsoft Platform Crypto Provider" i.e. the TPM
0 //Flags
);
try
{
BCryptGenRandom(hAlgorithm, @result[0], desiredBytes, 0);
}
finally
{
BCryptCloseAlgorithmProvider(hAlgorithm);
}
return result;
}
Fancy Thing
Zdaję sobie sprawę, że liczba osób korzystających z TPM jest bardzo mała. Dlatego nikt w Stackoverflow nie ma odpowiedzi. Więc nie mogę być zbyt chciwy w znalezieniu rozwiązania mojego powszechnego problemu. Ale to, co naprawdę chciałbym zrobić, to „zapieczętować” niektóre dane:
- przedstawić TPM pewne dane (np. 32 bajty materiału klucza)
- mają moduł TPM zaszyfrować dane, zwracając jakąś nieprzezroczystą strukturę obiektu blob
- później poproś moduł TPM o odszyfrowanie obiektu BLOB
- odszyfrowanie zadziała tylko wtedy, gdy rejestry PCR modułu TPM będą takie same, jak podczas szyfrowania.
Innymi słowy:
Byte[] ProtectBytes_TPM(Byte[] plaintext, Boolean sealToPcr)
{
//...
}
Byte[] UnprotectBytes_TPM(Byte[] protectedBlob)
{
//...
}
Cryptography Next Gen (Cng, aka BCrypt) obsługuje TPM
Oryginalny Cryptography API w Windows był znany jako Crypto API.
Począwszy od systemu Windows Vista, Crypto API zostało zastąpione przez Cryptography API: Next Generation (wewnętrznie znane jako BestCrypt , w skrócie BCrypt , którego nie należy mylić z algorytmem haszowania haseł ).
Windows jest dostarczany z dwoma dostawcami BCrypt :
- Domyślnie Microsoft Primitive Provider (
MS_PRIMITIVE_PROVIDER
) : domyślna implementacja oprogramowania wszystkich elementów pierwotnych (haszowanie, szyfrowanie symetryczne, podpisy cyfrowe itp.) - Microsoft Platform Crypto Provider (
MS_PLATFORM_CRYPTO_PROVIDER
): Dostawca zapewniający dostęp do modułu TPM
Platforma Crypto dostawcy nie są udokumentowane na MSDN, ale ma dokumentację z witryny Microsoft Research 2012:
Platforma TPM Crypto-Provider Toolkit
Dostawca usług kryptograficznych platformy TPM i zestaw narzędzi zawiera przykładowy kod, narzędzia i dokumentację do korzystania z funkcji związanych z modułem TPM w systemie Windows 8. Opisane podsystemy obejmują dostawcę usług kryptograficznych platformy Crypto-Next-Gen (CNG) opartej na technologii TPM oraz dostawców usług poświadczających mogą korzystać z nowych funkcji systemu Windows. Obsługiwane są systemy oparte na module TPM1.2 i TPM2.0.
Wydaje się, że intencją Microsoft jest TPM powierzchnia funkcjonalności krypto z dostawcy Microsoft Platform Crypto z Cryptography NG API.
Szyfrowanie klucza publicznego za pomocą Microsoft BCrypt
Jeśli się uwzględni:
- chcę wykonać asymetryczne szyfrowanie RSA (przy użyciu modułu TPM)
- Microsoft BestCrypt obsługuje asymetryczne szyfrowanie RSA
- Microsoft BestCrypt ma dostawcę TPM
wyjściem może być ustalenie, jak wykonać podpis cyfrowy przy użyciu interfejsu Microsoft Cryptography Next Gen API .
Następnym krokiem będzie wymyślenie kodu do szyfrowania w BCrypt, z publicznym kluczem RSA, przy użyciu standardowego provider ( MS_PRIMITIVE_PROVIDER
). Na przykład:
modulus
: 0xDC 67 FA F4 9E F2 72 1D 45 2C B4 80 79 06 A0 94 27 50 8209 DD 67 CE 57 B8 6C 4A 4F 40 9F D2 D1 69 FB 995D 85 0C 07 A1 F9 47 1B 56 16 6E F6 7F B9 CF 2A 58 36 37 99 29 AA 4F A8 12 E8 4F C7 82 2B 9D 72 2A 9C DE 6F C2 EE 12 6D CF F0 F2 B8 C4 DD 7C 5C 1A C8 17 51 A9 AC DF 08 22 04 9D 2B D7 F9 4B 09 DE 9A EB 5C 51 1A D8 F8 F9 56 9E F8 FB 37 9B 3F D3 74 65 24 0D FF 34 75 57 A4 F5 BF 55publicExponent
: 65537
Mając ten kod działający, mogę przełączyć się na używanie dostawcy TPM ( MS_PLATFORM_CRYPTO_PROVIDER
).
22.02.2016: A ponieważ Apple jest zmuszony pomóc odszyfrować dane użytkownika, pojawiło się ponowne zainteresowanie tym, jak sprawić, by TPM wykonywał najprostsze zadanie, do którego został wymyślony - zaszyfrowanie czegoś.
To mniej więcej tak, jakby każdy posiadał samochód, ale nikt nie wie, jak go uruchomić. Może robić naprawdę przydatne i fajne rzeczy, gdybyśmy tylko mogli przejść przez krok 1 .
Czytanie bonusowe
źródło
Odpowiedzi:
Elementarz
Wszystko, co następuje, dotyczy TPM 1.2. Należy pamiętać, że firma Microsoft wymaga modułu TPM 2.0 we wszystkich przyszłych wersjach systemu Windows. Generacja 2.0 różni się zasadniczo od wersji 1.2
Ze względu na zasady projektowania TPM nie ma rozwiązania jednokreskowego. Pomyśl o module TPM jak o mikrokontrolerze z ograniczonymi zasobami. Głównym celem projektowym było bycie tanim, a jednocześnie bezpiecznym. Tak więc moduł TPM został pozbawiony całej logiki, która nie była konieczna do bezpiecznej operacji. Tak więc TPM działa tylko wtedy, gdy masz przynajmniej trochę mniej lub bardziej grubego oprogramowania, wydając wiele poleceń we właściwej kolejności. A te sekwencje poleceń mogą być bardzo złożone. Dlatego TCG określiło TSS z dobrze zdefiniowanym API. Jeśli chcesz iść drogą Java, jest nawet API Java na wysokim poziomie . Nie znam podobnego projektu dla C # / .net
Rozwój
W twoim przypadku proponuję przyjrzeć się oprogramowaniu TPM IBM.
W opakowaniu znajdziesz 3 bardzo przydatne komponenty:
Niekoniecznie potrzebujesz programowego emulatora TPM, możesz także połączyć się z HW TPM urządzenia. Możesz jednak przechwycić wydane polecenia i spojrzeć na odpowiedzi, dzięki czemu dowiesz się, jak są one składane i jak odpowiadają specyfikacji polecenia.
Wysoki poziom
Wymagania wstępne:
Aby zapieczętować kroplę, musisz wykonać następujące czynności:
Aby odpieczętować, musisz:
Możesz przechowywać obiekt BLOB klucza w strukturze danych, której używasz do przechowywania chronionych bajtów.
Większość potrzebnych poleceń TPM to polecenia autoryzowane. Dlatego w razie potrzeby musisz ustanowić sesje autoryzacyjne. AFAIR to głównie sesje OSAP.
Polecenia TPM
Obecnie nie mogę uruchomić wersji do debugowania, więc nie mogę podać dokładnej kolejności. Więc potraktuj to jako nieuporządkowaną listę poleceń, których będziesz musiał użyć:
TPM_OSAP
TPM_CreateWrapKey
TPM_LoadKey2
TPM_Seal
Jeśli chcesz również odczytać aktualne wartości PCR:
TPM_PCRRead
źródło
Zaufane i zaszyfrowane klucze
Zaufane i zaszyfrowane klucze to dwa nowe typy kluczy dodane do istniejącej usługi pierścienia kluczy jądra. Oba te nowe typy są kluczami symetrycznymi o zmiennej długości iw obu przypadkach wszystkie klucze są tworzone w jądrze, a przestrzeń użytkownika widzi, przechowuje i ładuje tylko zaszyfrowane obiekty blob. Zaufane klucze wymagają dostępności chipa Trusted Platform Module (TPM) w celu zwiększenia bezpieczeństwa, podczas gdy szyfrowane klucze mogą być używane w dowolnym systemie. Wszystkie obiekty blob na poziomie użytkownika są wyświetlane i ładowane w postaci szesnastkowej ascii dla wygody i są weryfikowane pod kątem integralności.
Zaufane klucze używają modułu TPM zarówno do generowania, jak i do pieczętowania kluczy. Klucze są zapieczętowane 2048-bitowym kluczem RSA w module TPM i opcjonalnie zapieczętowane do określonych wartości PCR (pomiar integralności) i otwierane tylko przez TPM, jeśli testy PCR i weryfikacja integralności plamki są zgodne. Załadowany zaufany klucz można aktualizować nowymi (przyszłymi) wartościami PCR, dzięki czemu klucze można łatwo migrować do nowych wartości pcr, na przykład podczas aktualizacji jądra i initramfs. Ten sam klucz może mieć wiele zapisanych obiektów blob pod różnymi wartościami PCR, więc wiele rozruchów jest łatwo obsługiwanych.
Domyślnie zaufane klucze są zapieczętowane pod numerem SRK, który ma domyślną wartość autoryzacji (20 zer). To może być ustawiony w momencie takeownership z programu narzędziowego do spodni za:
tpm_takeownership -u -z
.keyctl print
zwraca szesnastkową kopię ascii zapieczętowanego klucza w standardowym formacie TPM_STORED_DATA. Długość klucza dla nowych kluczy jest zawsze w bajtach. Zaufane klucze mogą mieć od 32 do 128 bajtów (256 - 1024 bity), górna granica mieści się w 2048-bitowej długości klucza SRK (RSA), z całą niezbędną strukturą / dopełnieniem.Zaszyfrowane klucze nie są zależne od modułu TPM i są szybsze, ponieważ używają algorytmu AES do szyfrowania / odszyfrowywania. Nowe klucze są tworzone z losowych liczb generowanych przez jądro i są szyfrowane / odszyfrowywane przy użyciu określonego klucza „głównego”. Klucz „główny” może być kluczem zaufanym lub kluczem użytkownika. Główną wadą zaszyfrowanych kluczy jest to, że jeśli nie są zakorzenione w zaufanym kluczu, są tak bezpieczne, jak szyfrowany klucz użytkownika. Dlatego główny klucz użytkownika powinien być ładowany w możliwie bezpieczny sposób, najlepiej na początku uruchamiania.
Odszyfrowana część zaszyfrowanych kluczy może zawierać prosty klucz symetryczny lub bardziej złożoną strukturę. Format bardziej złożonej struktury zależy od aplikacji, którą określa się za pomocą „formatu”.
Przykłady użycia zaufanego i zaszyfrowanego klucza
Utwórz i zapisz zaufany klucz o nazwie „kmk” o długości 32 bajtów:
Załaduj zaufany klucz z zapisanego obiektu BLOB:
Odśwież zaufany klucz pod nowymi wartościami pcr:
Początkowym odbiorcą zaufanych kluczy jest EVM, który w czasie uruchamiania potrzebuje wysokiej jakości klucza symetrycznego do ochrony metadanych plików za pomocą HMAC. Użycie zaufanego klucza zapewnia silne gwarancje, że klucz EVM nie został naruszony przez problem na poziomie użytkownika, a po zapieczętowaniu do określonych wartości rozruchowego PCR chroni przed atakami podczas rozruchu i offline. Utwórz i zapisz zaszyfrowany klucz „evm”, używając powyższego zaufanego klucza „kmk”:
opcja 1: pomijanie „formatowania”
opcja 2: jawne zdefiniowanie „formatu” jako „domyślnego”
Załaduj zaszyfrowany klucz „evm” z zapisanego obiektu BLOB:
Przewidywane są inne zastosowania zaufanych i zaszyfrowanych kluczy, na przykład do szyfrowania dysków i plików. W szczególności nowy format „ecryptfs” został zdefiniowany w celu użycia zaszyfrowanych kluczy do zamontowania systemu plików eCryptfs. Więcej szczegółów na temat użycia można znaleźć w pliku „Documentation / security / keys-ecryptfs.txt”.
źródło
Documentation/security/keys-ecryptfs.tx
Zależy od Twoich zamiarów i okoliczności:
Każdy z tych przypadków użycia (a jest ich więcej) - lub ich kombinacja - przedstawia inną ścieżkę implementacji. Pomyśl o TPM jak o szwajcarskim scyzoryku urządzeń kryptograficznych: niewiele można z nim zrobić, ale łatwość użycia cierpi na tę wszechstronność. Pytanie ciągle przeskakuje między szyfrowaniem, podpisywaniem i blokowaniem do konfiguracji systemu, ale główna część tej odpowiedzi zakłada, że polecenie Seal spełnia większość potrzeb opisanych w pytaniu.
Do tego służy polecenie Bind (zastąpione przez polecenie Create dla modułu TPM 2). Ładujesz klucz, który pochodzi z klucza związanego z modułem TPM i szyfrujesz za jego pomocą (lub bezpośrednio za pomocą klucza sprzętowego). W ten sposób dane można odszyfrować tylko przy dostępie do tego samego modułu TPM.
Nie jestem pewien, czy powtórzenie całego procesu jest dobrym pomysłem. Po pierwsze, nie ma potrzeby wykonywania operacji podpisywania w dowolnym miejscu procesu. Wydawałoby się, że w czasie, gdy powstawał Android 5, API Keystore ograniczało się do operacji podpisywania i weryfikacji. Domyślam się, że zespół szyfrujący dysk dołożył wszelkich starań, aby pracować z tym, co miał, i opracował algorytm, w którym jeden z kluczy pośrednich został wyprowadzony podczas operacji podpisywania , przy użyciu przechowywanego klucza TEE, wiążąc w ten sposób cały proces ze sprzętem. związany klucz dostępny tylko na platformie - ponieważ podpisywanie było wówczas jedynym sposobem na to. Nie ma jednak potrzeby ograniczania się w taki sposób, jeśli masz dostęp do modułu TPM, który zapewnia więcej możliwości, niż wiedziałeś, że potrzebujesz!
To nieprawda, obie wersje obsługują podpisywanie TPM.
To nie ma sensu. Podpisanie tych samych danych tym samym kluczem da taki sam podpis. Możesz pomylić operację podpisywania z operacją cytowania, która będzie mieszała się z wartością jednorazową.
To faktycznie powinna być preferowana opcja, chociaż obie są możliwe w przypadku modułu TPM. Patrz wyżej.
Niestety nie ma wiele do udokumentowania. Win API jest ograniczone do kilku funkcji TBS, które są o jeden poziom usunięte ze sterownika.
Właściwie nie, gdybyś miał TSS, nie musiałbyś go używać
Tbsip_submit_Command()
. O to właśnie chodzi w przypadku TSS - szczegóły niskiego poziomu są wyabstrahowane.Nadal prawdziwe dla TPM 1, ale dla TPM 2 istnieje TSS.MSR .
Poprawny.
Nie jest jasne, czy jest to wyzwanie nie do pokonania. Dostęp do TrouSerS poprzez interop powinien być lepszy niż przepisanie całego kodu strukturyzującego dane. Było też
doTSS
w momencie pisania pytania.Pytanie zawiera cytat opisujący różnicę między tymi dwoma poleceniami, więc nie powinno być dużego zamieszania. Pieczętowanie jest podobne do wiązania, z dodatkowym ograniczeniem, że stan systemu musi być taki sam, aby dane mogły zostać rozpieczętowane.
Po pierwsze, warto zauważyć, że istnieją dwie główne wersje TPM, które są całkowicie niekompatybilne między sobą. Więc praktycznie żaden kod, który napisałeś dla TPM 1 nie będzie działał dla TPM 2. Interfejs API TBS jest jedynym wspólnym kodem między nimi i, aby być uczciwym dla firmy Microsoft, mógł to być jeden z powodów, dla których ten interfejs API nigdy się nie rozwinął. W głównej części odpowiedzi zostanie przedstawiony kod TPM 1 z dwóch powodów:
Po drugie, sprecyzujmy pytanie. Reinterpretuję to następująco:
Do tego celu najlepiej nadaje się polecenie Seal, ponieważ spełnia tę samą funkcję, co polecenie Bind, gdy wielkość selekcji PCR jest ustawiona na zero, ale wybór PCR można łatwo zmienić, aby uwzględnić dowolne reakcje PCR. To sprawia, że można się zastanawiać, dlaczego polecenie Bind zostało w ogóle uwzględnione w specyfikacji i jak zauważono, zostało usunięte ze specyfikacji TPM 2 i oba zostały połączone w jednym poleceniu Create.
Oto kod C # do używania polecenia TPM 1.2 Seal do szyfrowania danych za pomocą tylko funkcji TBS (uwaga: ten kod jest nieprzetestowany i prawdopodobnie nie zadziała bez debugowania) :
Analiza kodu:
To tylko niektóre z nielicznych funkcji dostępnych w Tbs.h i jedyne, których będziemy tutaj używać. Zasadniczo pozwalają one otworzyć uchwyt do urządzenia i komunikować się z nim, wysyłając i odbierając nieprzetworzone bajty.
TPM to big endian, Windows to little endian. Więc kolejność bajtów będzie musiała zostać odwrócona dla wszystkich przesyłanych danych. Musimy się tylko martwić o odwrócenie 32-bitowych i 16-bitowych intów bez znaku.
Tutaj używamy Tbsi_Context_Create (), aby otworzyć dojście do komunikacji z TPM.
TBS_CONTEXT_PARAMS
Parametr jest tylko struct C z jednym 32-bit unsigned int pole, które musi być ustawiony na 1, aby rozmawiać z TPM 1.2 instancji, a tym, co możemy ustawić go.Jest to określane jako minimalny rozmiar buforu w specyfikacji klienta komputera TPM . Tutaj wystarczy na nasze potrzeby.
TPM 1.2 Spec Part 3 mówi, co następuje:
Musimy zaszyfrować XOR ten „tajny” parametr przy użyciu wartości jednorazowej wygenerowanej podczas sesji OSAP. Jeden z uchwytów wejściowych polecenia Seal jest również uchwytem OSAP:
Więc najpierw musimy ustanowić tę sesję OSAP. OSAP jest opisany w specyfikacji TPM 1.2 Część 1 . Protokół OSAP, czyli protokół autoryzacji specyficzny dla obiektu, został wynaleziony do obsługi przypadku użycia, w którym chcesz użyć obiektu TPM, który wymaga wielokrotnej autoryzacji, ale nie chce zapewniać autoryzacji za każdym razem: zamiast tego używana jest sesja OSAP, która polega na na temat „wspólnego sekretu”, którym jest HMACktóry miesza dane autoryzacji obiektu z danymi nonce wygenerowanymi po każdej stronie, aby zapobiec atakom odpowiedzi. Dlatego „wspólne hasło” jest znane tylko dwóm stronom w tej sesji: stronie, która zainicjowała sesję (użytkownik) i stronie, która ją zaakceptowała (TPM); ponadto obie strony muszą mieć te same dane autoryzacji obiektu, aby „wspólne hasło” było takie samo; dodatkowo „wspólne hasło” użyte w jednej sesji będzie nieważne w innej. Ten diagram ze specyfikacji opisuje proces:
W tym konkretnym przypadku nie będziemy używać wielu sesji (w rzeczywistości ten parametr jest ignorowany przez polecenie Seal!), A klucz, którego będziemy używać, nie wymaga autoryzacji, ale niestety nadal jesteśmy zobowiązani do ustanowienia OSAP sesja.
Argumenty polecenia TPM_OSAP to:
Każde polecenie TPM 1.2 ma następującą strukturę:
Znacznik jest dwubajtową wartością, która wskazuje, czy to, co następuje, jest wejściem, czy wyjściem i czy istnieją jakieś wartości danych uwierzytelniania po parametrach polecenia. W przypadku TPM_OSAP tag musi mieć wartość TPM_TAG_RQU_COMMAND (0x00C1) zgodnie ze specyfikacją, co oznacza „polecenie bez autoryzacji”.
Rozmiar to czterobajtowa wartość określająca rozmiar polecenia w bajtach, w tym znacznik i sam rozmiar. Wartość tę ustawimy później, po jej obliczeniu.
Kod polecenia to czterobajtowa wartość, która służy jako identyfikator polecenia: informuje moduł TPM, jak zinterpretować pozostałą część polecenia. Nasz kod polecenia to TPM_OSAP (0x0000000B).
Następne dwie rzeczy do ustawienia to typ jednostki i wartość jednostki. Ponieważ chcemy użyć klucza, który już istnieje w module TPM, użyjemy typu jednostki „SRK” (0x0004), a ponieważ pracujemy przy założeniu, że moduł TPM jest już własnością, można bezpiecznie założyć, że ma SRK załadowany pod stałym uchwytem 0x40000000 zgodnie ze specyfikacją, więc użyjemy tej trwałej wartości uchwytu dla naszej wartości encji. (SRK oznacza „Storage Root Key” i jest kluczem głównym, z którego pochodzi większość innych kluczy należących do modułu TPM)
Na koniec obliczamy rozmiar polecenia, ustawiamy go i wysyłamy polecenie.
Dane, które powinniśmy odzyskać z TPM na TPM_OSAP to:
Więc wracamy:
Wyodrębniamy te wartości i przechowujemy je w zmiennych.
Następnie obliczamy „wspólny sekret”. Zgodnie ze specyfikacją, wartościami uwzględnianymi w obliczeniach są dwie wartości nonce OSAP (jedna wygenerowana przez użytkownika i jedna wygenerowana przez TPM) oraz wartość autoryzacji dla klucza, którego chcemy użyć - SRK. Zgodnie z konwencją, wartość autoryzacji SRK jest „dobrze znanym auth”: zerowanym 20-bajtowym buforem. Technicznie rzecz biorąc, można zmienić tę wartość na inną, przejmując na własność TPM, ale nie jest to robione w praktyce, więc możemy bezpiecznie założyć, że wartość „dobrze znanego uwierzytelnienia” jest dobra.
Następnie przyjrzyjmy się, co trafia do polecenia TPM_Seal:
Większość z tych parametrów jest trywialnych do zbudowania, z wyjątkiem dwóch z nich:
encAuth
ipubAuth
. Spójrzmy na nie jeden po drugim.encAuth
to „Zaszyfrowane dane AuthData dla zapieczętowanych danych”. Nasze AuthData to „dobrze znana autoryzacja” z wcześniej, ale tak, nadal musimy ją zaszyfrować. Ponieważ używamy sesji OSAP, jest ona szyfrowana zgodnie z protokołem ADIP lub Authorization-Data Insertion Protocol. Ze specyfikacji: „ADIP pozwala na tworzenie nowych jednostek i bezpieczne wstawianie nowej jednostki AuthData. Transmisja nowego AuthData wykorzystuje szyfrowanie za pomocą klucza opartego na wspólnym tajnym tajne sesji OSAP”. Dodatkowo: „W przypadku obowiązkowego algorytmu szyfrowania XOR twórca tworzy klucz szyfrowania przy użyciu skrótu SHA-1 wspólnego hasła OSAP i numeru sesji. Twórca XOR szyfruje nowe dane AuthData przy użyciu klucza szyfrowania jako jednorazowej podkładki i wysyła te zaszyfrowane dane wraz z żądaniem utworzenia do modułu TPM ”.Poniższy diagram wyjaśnia, jak działa ADIP:
pubAuth
to „Podsumowanie sesji autoryzacji dla danych wejściowych i keyHandle”. Część 1 specyfikacji, w „Deklaracjach parametrów dla przykładów OIAP i OSAP”, wyjaśnia, jak interpretować powyższą tabelę parametrów TPM_Seal: „Kolumna HMAC # zawiera szczegółowe informacje na temat parametrów używanych w obliczeniach HMAC. Parametry 1S, 2S itd. Są łączone i hashowane do inParamDigest lub outParamDigest, niejawnie nazywane 1H1 i prawdopodobnie 1H2, jeśli istnieją dwie sesje autoryzacji. W przypadku pierwszej sesji 1H1, 2H1, 3H1 i 4H1 są łączone i HMAC. W przypadku drugiej sesji 1H2, 2H2, 3H2, i 4H2 są łączone i HMAC ''. Więc będziemy musieliencAuth
zaszyfrować tekst jawny, jego rozmiar, rozmiar informacji PCR, od góry i numer porządkowy TPM_Seal, a następnie HMAC, który z dwiema wartościami nonces i wartością logiczną „kontynuuj sesję” przy użyciu OSAP ”Podsumowując to wszystko na schemacie:
Zwróć uwagę, jak ustawiliśmy „rozmiar informacji PCR” na zero w tym kodzie, ponieważ chcemy po prostu zaszyfrować dane bez blokowania ich w stanie systemowym. Jednak w razie potrzeby podanie struktury „informacji o PCR” jest trywialne.
Na koniec tworzymy polecenie i wysyłamy.
Używamy funkcji Tbsip_Context_Close (), aby zamknąć nasz uchwyt komunikacyjny.
Zwracamy odpowiedź taką, jaka jest tutaj. Idealnie byłoby, gdybyś chciał ponownie odwrócić bajty i sprawdzić poprawność przez ponowne
resAuth
obliczenie wartości, aby zapobiec atakom typu man-in-the-middle.Dzieje się tak, ponieważ Tspi_Data_Bind jest poleceniem TSS, a nie poleceniem TPM. Powodem jest to, że nie wymaga żadnych tajemnic (używany jest tylko klucz publiczny), więc można to zrobić bez angażowania modułu TPM. Spowodowało to jednak zamieszanie, a nawet polecenia, które nie wymagają żadnych tajemnic, są teraz zawarte w specyfikacji TPM 2.
Zależy od wersji TPM. Za pomocą komendy TPM_CreateWrapKey dla TPM 1.2. Za pomocą polecenia TPM2_Create dla modułu TPM 2.
Utwórz go w module TPM, zapakuj go lub użyj dowolnej innej z dostępnych metod.
Tekst w książce jest zagmatwany. Nie określasz klucza HMAC , określasz, że chcesz mieć klucz HMAC .
Nie, to nie ma sensu. Klucz jest tajny.
Istnieją polecenia służące do tworzenia kluczy lub importowania ich dla obu wersji TPM. W przypadku modułu TPM 1 był tylko jeden klucz główny - SRK - z którego można było ustalić hierarchię kluczy, tworząc klucze opakowane. Dzięki TPM 2 możesz mieć wiele kluczy podstawowych lub głównych.
Patrz wyżej.
Prawdopodobnie zależy to od rodzaju napędu. W przypadku dysków bez SED klucz szyfrowania dysku jest prawdopodobnie owinięty kluczem TPM. W przypadku dysków SED hasło administratora 1 (lub takie) jest zapieczętowane za pomocą modułu TPM.
EK nie jest kluczem do podpisywania - to klucz szyfrowania. Jednak nie jest to klucz szyfrowania ogólnego przeznaczenia: można go używać tylko w określonych kontekstach .
Patrz wyżej.
źródło
Kiedy mówi
NIE oznacza to podania klucza HMAC - oznacza „wskazanie klucza HMAC, którego chcesz użyć” .
Moduły TPM mogą używać praktycznie nieograniczonej liczby kluczy HMAC, jak wskazano w książce. Musisz powiedzieć modułowi TPM, którego ma użyć.
źródło