2

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?

ToBu
  • 95
  • 1
  • 7

2 Answers2

0

Microsoft.Azure.Devices.Provisioning.Security.Tpm is relying on Microsoft.TSS 2.0.1 NuGet Package which has only binaries for linux-x64.

In order to make it work:

  1. git clone TSS.MSR and azure-iot-sdk-csharp
  2. in /TSS.NET/TSS.Net/TSS.Net.csproj change this:
<PropertyGroup Condition=" '$(RuntimeIdentifier)' == 'linux-x64' Or '$(OS)' == 'Unix'  Or '$(OS)' == 'Linux'">

to this

<PropertyGroup Condition=" '$(RuntimeIdentifier)' == 'linux-x64' Or '$(RuntimeIdentifier)' == 'linux-arm' Or '$(OS)' == 'Unix'  Or '$(OS)' == 'Linux'">
  1. Reference the TSS.Net.csproj in Microsoft.Azure.Devices.Provisioning.Security.Tpm

  2. Reference Microsoft.Azure.Devices.Provisioning.Security.Tpm.csproj in your project, instead of the NuGet package

  3. dotnet build --runtime linux-arm --configuration Release

  • thx for your reply. I tried it out, but sadly run into the same error. The trace is a bit clearer (-> BcryptInterface.cs) ``` [DllImport("bcrypt.dll", CharSet = CharSet.Unicode)] internal static extern int BCryptOpenAlgorithmProvider( out UIntPtr AlgProvider, [Interop.MarshalAs(UnmanagedType.LPWStr), In] String AlgId, [Interop.MarshalAs(UnmanagedType.LPWStr), In] String Implementati ``` But I don't know how to get the missing depedency in there. – ToBu Feb 11 '19 at 15:46
0

The Microsoft.TSS package had a pre-compiler error in it that included some code when compiling for non-Windows that it shouldn't have. It has since been fixed. However, they hadn't shipped a new version, so the Azure IoT SDK hasn't had access to that fix.

Ownership has changed hands on that repo and we (the Azure IoT SDK team) have been working with them to get it released, but we need the .netstandard2.0 NuGet target added back first.

As soon as we have a viable release from Microsoft.TSS, we'll update our reference and ship again. In the intervening time, you'd be able to manually add that updated NuGet reference to your device app.

Keep an eye on our releases page for a notification of an updated NuGet reference.