Как зашифровать байты с помощью TPM (Trusted Platform Module)

Как я могу зашифровать байты, используя модуль TPM машины?

CryptProtectData

Windows предоставляет (относительно) простой API для шифрования большого двоичного объекта с использованиемCryptProtectData API, который мы можем обернуть простой в использовании функцией:

public Byte[] ProtectBytes(Byte[] plaintext)
{
   //...
}

ДеталиProtectBytes менее важны, чем идея, что вы можете использовать его довольно легко:

вот байты, которые я хочу зашифровать секретным ключом, хранящимся вSystemверни мне зашифрованный блоб

Возвращенныйкапля недокументированныйдокументация структура, которая содержит все необходимое для расшифровки и возврата исходных данных (алгоритм хеширования, алгоритм шифрования, соль, сигнатура HMAC и т. д.).

Для полноты вот пример реализации псевдокодаProtectBytes который используетCrypt API для защиты байтов:

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.
}
Как сделать то же самое с TPM?

Приведенный выше код полезен для шифрования данных только на локальном компьютере. Данные зашифрованы с использованиемSystem аккаунт как генератор ключей (детали, хотя и интересные, не важны). Конечным результатом является то, что я могу зашифровать данные (например, главный ключ шифрования жесткого диска), которые могут быть расшифрованы только на локальной машине.

Теперь пришло время сделать еще один шаг вперед. Я хочу зашифровать некоторые данные (например, главный ключ шифрования жесткого диска), которые могут быть расшифрованы только локальным TPM. Другими словами, я хочу заменить среду надежного выполнения Qualcomm (TEE) в блок-схеме ниже для Android, с TPM в Windows:

ЗаметкаЯ понимаю, что доверенный платформенный модуль не выполняет подписывание данных (или, если это так, не гарантирует, что подписывание одних и тех же данных каждый раз будет давать одинаковые двоичные данные). Вот почему я был бы готов заменить«Подписание RSA» с«шифрование 256-битного двоичного объекта с помощью аппаратного связанного ключа».

Так где же код?

Проблема в том, что программирование TPMполностью недокументированный на MSDN, Нет API для выполнения каких-либо операций. Вместо этого вы должны найти себе копиюПрограммный стек Trusted Computing Group (он же TSS)выяснить, какие команды отправлять в TPM, с полезными нагрузками, в каком порядке и вызыватьокнаTbsip_Submit_Command функция подавать команды напрямую:

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
);

В Windows нет API более высокого уровня для выполнения действий.

Это моральный эквивалент попытки создать текстовый файл с помощью команд ввода-вывода SATA на жесткий диск.

Почему бы просто не использовать брюки

Trusted Computing Group (TCG) действительно определила свой собственный API:Программный стек TCB (ТСС), Реализация этого API была создана некоторыми людьми и называетсяБрюки, Парень топеренес этот проект в Windows.

Проблема этого кода в том, что он не переносим в мир Windows. Например, вы не можете использовать его из Delphi, вы не можете использовать его из C #. Это требует:

OpenSSLPTHREAD

Я просто хочукод чтобы зашифровать что-то с моим TPM.

ВышеCryptProtectData не требует ничего, кроме того, что находится в теле функции.

Какой эквивалентный код используется для шифрования данных с помощью TPM? Как отметили другие,вам, вероятно, придется обратиться к трем руководствам TPM и создать собственные объекты., Это, вероятно, включает в себяTPM_seal команда. Хотя я думаю, что я не хочупечать данные, я думаю, что я хочупривязывать Это:

переплет - шифрует данные, используя ключ привязки TPM, уникальный ключ RSA, полученный из ключа хранения.Уплотнительные - шифрует данные аналогично привязке, но дополнительно указывает состояние, в котором TPM должен находиться для того, чтобы данные были расшифрованы (незапечатаны)

Я пытаюсь прочитать три необходимых тома, чтобы найти нужные мне 20 строк кода:

Часть 1 - Принципы проектированияЧасть 2 - Структуры TPMЧасть 3 - Команды

Но у меня естьнет Идея, что я читаю. Если бы был какой-то учебник или примеры, я мог бы попробовать. Но я полностью потерян.

Поэтому мы просим Stackoverflow

Таким же образом я смог обеспечить:

Byte[] ProtectBytes_Crypt(Byte[] plaintext)
{
   //...
   CryptProtectData(...); 
   //...
}

Может ли кто-нибудь предоставить соответствующий эквивалент:

Byte[] ProtectBytes_TPM(Byte[] plaintext)
{
   //...
   Tbsip_Submit_Command(...);
   Tbsip_Submit_Command(...);
   Tbsip_Submit_Command(...);
   //...snip...
   Tbsip_Submit_Command(...);
   //...
}

это делает то же самое, за исключением того, что ключ запертSystem ЛСА, заблокирован в TPM?

Начало исследований

Я точно не знаю чтопривязывать средства. Но, глядя на TPM Main - Команды части 3 - Спецификация версии 1.2, есть упоминание опривязывать:

10.3 TPM_UnBind

TPM_UnBind берет большой двоичный объект данных, являющийся результатом команды Tspi_Data_Bind, и расшифровывает его для экспорта пользователю. Вызывающий должен разрешить использование ключа, который расшифрует входящий BLOB-объект. TPM_UnBind работает на блочной основе и не имеет представления о каких-либо отношениях между одним блоком и другим.

Что смущает тамявляется нетTspi_Data_Bind команда.

Исследования усилий

Страшно, как никто не удосужился документировать TPM или его работу. Как будто они провели все свое время, придумывая этот крутойвещь играть, но не хотел иметь дело с болезненным шагом сделать этогодный к употреблению для чего-то.

Начиная с (сейчас) бесплатной книгиПрактическое руководство по TPM 2.0: использование доверенного платформенного модуля в новую эпоху безопасности:

Глава 3 - Краткое руководство по TPM 2.0

TPM имеет доступ к самогенерируемому закрытому ключу, поэтому он может зашифровать ключи открытым ключом и затем сохранить полученный большой двоичный объект на жестком диске. Таким образом, TPM может хранить практически неограниченное количество ключей, доступных для использования, но не тратить ценное внутреннее хранилище. Ключи, хранящиеся на жестком диске, могут быть стерты, но они также могут быть скопированы, что показалось дизайнерам приемлемым компромиссом.

Как я могу зашифровать ключ с помощью открытого ключа TPM?

Глава 4 - Существующие приложения, использующие доверенные платформенные модулиПриложения, которые должны использовать TPM, но не

В последние несколько лет количество веб-приложений увеличилось. Среди них - сетевое резервное копирование и хранение. В настоящее время большое количество компаний предлагают такие услуги, но, насколько нам известно, ни один из клиентов этих служб не позволяет пользователю заблокировать ключ для службы резервного копирования в доверенном платформенном модуле. Если бы это было сделано, было бы неплохо создать резервную копию самого ключа TPM, дублируя его на нескольких компьютерах. Это представляется возможностью для разработчиков.

Как разработчик блокирует ключ к TPM?

Глава 9 - HeirarchiesПРИМЕР ИСПОЛЬЗОВАНИЯ: ХРАНЕНИЕ ПАРОЛЕЙ ВХОДА

Типичный файл паролей хранит соленые хэши паролей. Проверка состоит из засолки и хэширования предоставленного пароля и сравнения его с сохраненным значением. Поскольку в расчет не входит секрет, он подвергается автономной атаке на файл паролей.

В этом случае используется ключ HMAC, созданный TPM. Файл паролей хранит HMAC соленого пароля. Проверка состоит из засолки и HMAC, предоставления предоставленного пароля и сравнения его с сохраненным значением. Поскольку у автономного злоумышленника нет ключа HMAC, злоумышленник не может провести атаку, выполнив расчет.

этомог Работа. Если у доверенного платформенного модуля есть секретный ключ HMAC, и только мой доверенный платформенный модуль знает ключ HMAC, то я мог бы заменить «Подписать (или шифровать TPM с помощью своего закрытого ключа)» на «HMAC». Но затем в следующей строке он полностью переворачивает себя:

TPM2_Create, указав ключ HMAC

Это не секрет TPM, если мне нужно указать ключ HMAC. Тот факт, что ключ HMAC не является секретным, имеет смысл, когда вы понимаете, что это глава о криптографических утилитах, которые предоставляет TPM. Вместо того, чтобы писать SHA2, AES, HMAC или RSA самостоятельно, вы можете повторно использовать то, что уже есть в TPM.

Глава 10 - Ключи

В качестве устройства безопасности, способность приложенияиспользуйте ключи, сохраняя их в безопасности на аппаратном устройстве самая большая сила TPM. TPM может генерировать и импортировать внешние ключи. Он поддерживает как асимметричные, так и симметричные ключи.

Отлично! Как ты делаешь это!?

Генератор ключей

Можно утверждать, что наибольшей силой TPM является его способность генерировать криптографический ключ и защищать его секрет в пределах аппаратного обеспечения. Генератор ключей основан на собственном генераторе случайных чисел TPM и не зависит от внешних источников случайности. Таким образом, он устраняет недостатки, основанные на слабом программном обеспечении с недостаточным источником энтропии.

Есть ли TPM имеют возможность генерировать криптографические ключи и защищать свои секреты в пределах аппаратных границ? Так как?

Глава 12 - Регистры конфигурации платформыПЦР для авторизацииПРИМЕР ИСПОЛЬЗОВАНИЯ: ЗАКРЫТИЕ ЖЕСТКОГО ДИСКА КЛЮЧ К ШИФРОВОМУ ПЛАТФОРМЕ

Приложения полнодискового шифрования намного более безопасны, если TPM защищает ключ шифрования, чем если он хранится на том же диске и защищен только паролем. Во-первых, оборудование TPM имеет защиту от перфорации (подробное описание защиты от словаря TPM в главе см. В главе 8), что делает нецелесообразной атаку паролем. Ключ, защищенный только программным обеспечением, гораздо более уязвим для слабого пароля. Во-вторых, программный ключ, хранящийся на диске, гораздо проще украсть. Возьмите диск (или резервную копию диска), и вы получите ключ. Когда TPM держит ключ, вся платформа, или, по крайней мере, диск и материнская плата, должны быть украдены.

Запечатывание позволяет защитить ключ не только паролем, но и политикой. Типичная политика блокирует ключ к значениям ПЦР (состоянию программного обеспечения), действующим на момент запечатывания. Это предполагает, что состояние при первой загрузке не скомпрометировано. Любое предустановленное вредоносное ПО, присутствующее при первой загрузке, будет измеряться в ПЦР, и, таким образом, ключ будет закрыт до состояния скомпрометированного программного обеспечения. Менее доверчивое предприятие может иметь стандартный образ диска и печать на ПЦР, представляющих этот образ. Эти значения ПЦР будут предварительно рассчитаны на предположительно более надежной платформе. Еще более изощренное предприятие будет использовать TPM2_PolicyAuthorize и предоставит несколько билетов для авторизации набора доверенных значений PCR. См. Главу 14 для подробного описания политики авторизации и ее применения для решения проблемы хрупкости PCR.

Хотя пароль также может защищать ключ, безопасность достигается даже без пароля ключа TPM. Злоумышленник может загрузить платформу без предоставления пароля TPMkey, но не может войти без имени пользователя и пароля операционной системы. OSsecurity защищает данные. Злоумышленник может загрузить альтернативную ОС, скажем, с живого DVD или USB-накопителя, а не с жесткого диска, чтобы обойти безопасность входа в ОС. Однако эта другая конфигурация загрузки и программное обеспечение могут изменить значения PCR. Поскольку эти новые PCR не будут соответствовать запечатанным значениям, TPM не выпустит ключ дешифрования, и жесткий диск не может быть расшифрован.

Отлично! Это именно тот случай использования, который мне нужен. Это также тот случай использования, для которого Microsoft использует TPM. Как мне это сделать!?

Поэтому я прочитал всю эту книгу, и она не дала ничего полезного. Что весьма впечатляет, потому что это 375 страниц. Вы задаетесь вопросом, что содержала книга - и оглядываясь назад, я понятия не имею.

Поэтому мы отказываемся от окончательного руководства по программированию TPM и обратимся к некоторой документации от Microsoft:

ОтНабор инструментов для шифрования провайдера платформы Microsoft TPM, Здесь упоминается именно то, что я хочу сделать:

Ключ одобрения или EK

EK разработан для обеспечения надежного криптографического идентификатора для платформы. Предприятие может поддерживать базу данных ключей одобрения, принадлежащих доверенным платформенным модулям всех ПК на своем предприятии, или контроллер фабрики центра обработки данных может иметь базу данных доверенных платформенных модулей во всех блейдах. В Windows вы можете использовать провайдера NCrypt, описанного в разделе «Платформа Crypto Provider в Windows 8», чтобы прочитать открытую часть EK.

Где-то внутри TPM находится закрытый ключ RSA. Этот ключ там заперт - его никогда не увидит внешний мир. Я хочу, чтобы доверенный платформенный модуль что-то подписал своим закрытым ключом (то есть зашифровал его своим закрытым ключом).

Поэтому я хочу больше всегоосновной операция, которая может существовать:

Зашифруйте что-нибудь с помощью своего закрытого ключа. Я даже (пока) не прошу более сложные вещи:

«Уплотнение» это основано на состоянии ПЦРсоздание ключа и сохранение его в энергозависимой или энергонезависимой памятисоздать симметричный ключ и попытаться загрузить его в TPM

Я прошу самую основную операцию, которую может выполнить TPM. Почему невозможно получить какую-либо информацию о том, как это сделать?

Я могу получить случайные данные

Я полагаю, что я был беспечным, когда сказал, что подписание RSA - это самое основное, что может сделать TPM.самый Основная вещь, которую может попросить TPM, - дать мне случайные байты.Тот Я понял, как это сделать:

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;
}
Причудливая вещь

Я понимаю, что количество людей, использующих TPM, очень мало. Вот почему никто на Stackoverflow не имеет ответа. Поэтому я не могу быть слишком жадным в решении моей общей проблемы. Но вещь, которую я быдействительно хочу сделать, это"печать" некоторые данные:

представить TPM некоторые данные (например, 32 байта ключевого материала)TPM шифрует данные, возвращая некоторую непрозрачную структуру BLOB-объектовпозже попросите TPM расшифровать блобдешифрование будет работать только в том случае, если регистры PCR TPM такие же, как и во время шифрования.

Другими словами:

Byte[] ProtectBytes_TPM(Byte[] plaintext, Boolean sealToPcr)
{
   //...
}

Byte[] UnprotectBytes_TPM(Byte[] protectedBlob)
{
   //...
}
Криптография Next Gen (Cng, aka BCrypt) поддерживает TPM

Оригинальный API шифрования в Windows был известен как API шифрования.

Начиная с Windows Vista, Crypto API был заменен наAPI криптографии: следующее поколение (внутренне известный какBestCryptсокращенно какBCrypt, не путать салгоритм хеширования пароля).

Windows поставляется с двумя BCryptпровайдеры:

Примитивный провайдер Microsoft (MS_PRIMITIVE_PROVIDER) дефолт: Стандартная программная реализация всехпримитивы (хеширование, симметричное шифрование, цифровые подписи и т. д.)Крипто провайдер платформы Microsoft (MS_PLATFORM_CRYPTO_PROVIDER): Поставщик, обеспечивающий доступ к TPM

Платформа Crypto Поставщик не зарегистрирован в MSDN, но имеет документацию с сайта Microsoft Research 2012:

Инструментарий криптографического провайдера платформы TPM

Поставщик криптографии и инструментарий платформы TPM содержит пример кода, утилиты и документацию для использования связанных с TPM функций в Windows 8. Описанные подсистемы включают криптографического провайдера платформы Crypto-Next-Gen (CNG) с поддержкой TPM и способы предоставления услуг аттестации можете использовать новые функции Windows. Поддерживаются как системы на основе TPM1.2, так и TPM2.0.

Похоже, что намерение Microsoft состоит в том, чтобы раскрыть криптографическую функциональность TPM с помощьюКрипто провайдер платформы Microsoft изКриптография НГ API.

Шифрование с открытым ключом с использованием Microsoft BCrypt

При условии:

я хочу выполнить асимметричное шифрование RSA (используя TPM)MicrosoftBestCrypt поддерживает RSA асимметричное шифрованиеMicrosoft BestCrypt имеетПоставщик TPM

путь вперед может заключаться в том, чтобы выяснить, как сделать цифровую подпись, используяMicrosoft Cryptography Next Gen API.

Следующим моим шагом будет создание кода для шифрования в BCrypt с открытым ключом RSA с использованием стандартного поставщика (MS_PRIMITIVE_PROVIDER). Например.:

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 F8 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

С этим функционалом кода, я могу быть в состоянии переключиться на использование поставщика TPM (MS_PLATFORM_CRYPTO_PROVIDER).

22.02.2016: А поскольку Apple вынуждена помогать расшифровывать пользовательские данные, вновь возникает интерес к тому, как заставить TPM выполнить самую простую задачу, для которой он был изобретен - шифрование чего-либо.

Это примерно равносильно тому, что у каждого есть машина, но никто не знает, как ее завести. Он может делать действительно полезные и крутые вещи, если бы только мы могли пройтиШаг 1.

Бонус ЧтениеAndroid - Шифрование - Хранение зашифрованного ключаAndroid Explorations - Пересматривая шифрование диска AndroidDPAPI Секреты. Анализ безопасности и восстановление данных в DPAPI (часть 1)

Ответы на вопрос(3)

Ваш ответ на вопрос