I want to use the azure-iot-sdk-csharp to provision a linux based device on the azure iot dps using TPM as authentification mechanism.
I added a TPM Module to a raspberry board and configured the kernel / deviceTree. The TPM chip is detected and the /dev/tpm0 device shows up in linux. Addionaly I included all prerequisite into the linux image to run a self contained .net-core app on linux (https://github.com/dotnet/core/blob/master/samples/YoctoInstructions.md). It is possible to run .net-core apps... I tested a simple Iot-Hub connection using the c# device-sdk.
Next, I tried to to access the TPM Module from .net core. Therefore I wrote this program, using the SecurityProviderTpmHsm from Microsoft.Azure.Devices.Provisioning.Security to read the TPM endorsementKey.
using System;
using System.Text;
using Microsoft.Azure.Devices.Provisioning.Security;
using Microsoft.Azure.Devices.Shared;
namespace TPMTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var tpmProvider = new SecurityProviderTpmHsm("test");
var test = tpmProvider.GetEndorsementKey();
Console.WriteLine(BitConverter.ToString(test));
}
}
}
This works on a windows machine, but fails on the linux-arm machine with a self contained package (dotnet publish -r linux-arm).
Hello World!
Unhandled Exception: System.DllNotFoundException: Unable to load shared library 'bcrypt.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libbcrypt.dll: cannot open shared object file: No such file or directory
at Tpm2Lib.Native.BCryptOpenAlgorithmProvider(UIntPtr& AlgProvider, String AlgId, String Implementation, UInt32 Flags)
at Tpm2Lib.BCryptAlgorithm.Open(String algName, UInt32 flags)
at Tpm2Lib.BCryptAlgorithm..ctor(String algName, UInt32 flags)
at Tpm2Lib.CryptoLib.Hmac(TpmAlgId hashAlgId, Byte[] key, Byte[] data)
at Tpm2Lib.KDF.KDFa(TpmAlgId hmacHash, Byte[] hmacKey, String label, Byte[] contextU, Byte[] contextV, Int32 numBitsRequired)
at Tpm2Lib.PRNG.FillRandBuf()
at Tpm2Lib.PRNG.SetRngRandomSeed()
at Tpm2Lib.PRNG.GetRandomBytes(Int32 numBytes)
at Tpm2Lib.Globs.GetRandomBytes(Int32 numBytes)
at Tpm2Lib.Tpm2.GetRandomBytes(Int32 numBytes)
at Tpm2Lib.Tpm2.CancelSafeStartAuthSession(TpmSe sessionType, TpmAlgId authHash, Int32 nonceCallerSize)
at Tpm2Lib.Tpm2.PrepareRequestSessions(CommandInfo commandInfo, TpmHandle[] inHandles)
at Tpm2Lib.Tpm2.DispatchMethod(TpmCc ordinal, TpmStructureBase inParms, Type expectedResponseType, TpmStructureBase& outParms, Int32 numInHandlesNotUsed, Int32 numOutHandlesNotUsed)
at Tpm2Lib.Tpm2.CreatePrimary(TpmHandle primaryHandle, SensitiveCreate inSensitive, TpmPublic inPublic, Byte[] outsideInfo, PcrSelection[] creationPCR, TpmPublic& outPublic, CreationData& creationData, Byte[]& creationHash, TkCreation& creationTicket)
at Microsoft.Azure.Devices.Provisioning.Security.SecurityProviderTpmHsm.ReadOrCreatePersistedKey(TpmHandle persHandle, TpmHandle hierarchy, TpmPublic template)
at Microsoft.Azure.Devices.Provisioning.Security.SecurityProviderTpmHsm.CacheEkAndSrk()
at Microsoft.Azure.Devices.Provisioning.Security.SecurityProviderTpmHsm..ctor(String registrationId, Tpm2Device tpm)
at Microsoft.Azure.Devices.Provisioning.Security.SecurityProviderTpmHsm..ctor(String registrationId)
at TPMTest.Program.Main(String[] args) in C:\Users\admin\source\repos\TPMTest\TPMTest\Program.cs:line 12
Aborted
I read some issues with the missing bcrypted.dll on github. As I understand, some cryptographic functions are not ported in .net core 2.x for linux. https://github.com/dotnet/corefx/issues/7023 So, I tried the .net-core 3.x preview, which supports AES-GCM etc. ... but I run into the same error.
Not sure, if this issue is related to my problme.
Is there a missing dependency, which I need in my linux image? Is it in general supported to use a TPM Module in .net-core on a linux based machine?