diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index 9606bfb..2e5e4fa 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -291,11 +291,18 @@ int wolfTPM2_FreeSession(WOLFTPM2_SESSION* session) WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromKey(WOLFTPM2_KEY* key) { - if (key == NULL) { - return NULL; - } - return &(key->handle); + return (key != NULL) ? &key->handle : NULL; } +WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromKeyBlob(WOLFTPM2_KEYBLOB* keyBlob) +{ + return (keyBlob != NULL) ? &keyBlob->handle : NULL; +} + +WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromSession(WOLFTPM2_SESSION* session) +{ + return (session != NULL) ? &session->handle : NULL; +} + int wolfTPM2_GetKeyBlobAsBuffer(byte *buffer, word32 bufferSz, WOLFTPM2_KEYBLOB* key) diff --git a/wolftpm/tpm2_wrap.h b/wolftpm/tpm2_wrap.h index fc58c54..48bf3ee 100644 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -2478,6 +2478,28 @@ WOLFTPM_API int wolfTPM2_FreeSession(WOLFTPM2_SESSION* session); */ WOLFTPM_API WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromKey(WOLFTPM2_KEY* key); +/*! + \ingroup wolfTPM2_Wrappers + \brief Retrieve the WOLFTPM2_HANDLE from a WOLFTPM2_KEYBLOB + + \return pointer to handle in the key blob structure + \return NULL if key pointer is NULL + + \param key pointer to a WOLFTPM2_KEYBLOB struct +*/ +WOLFTPM_API WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromKeyBlob(WOLFTPM2_KEYBLOB* keyBlob); + +/*! + \ingroup wolfTPM2_Wrappers + \brief Retrieve the WOLFTPM2_HANDLE from a WOLFTPM2_SESSION + + \return pointer to handle in the session structure + \return NULL if key pointer is NULL + + \param key pointer to a WOLFTPM2_SESSION struct +*/ +WOLFTPM_API WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromSession(WOLFTPM2_SESSION* session); + /*! \ingroup wolfTPM2_Wrappers \brief Set the authentication data for a key diff --git a/wrapper/CSharp/wolfTPM-tests.cs b/wrapper/CSharp/wolfTPM-tests.cs index 7f6748e..9a85e6e 100644 --- a/wrapper/CSharp/wolfTPM-tests.cs +++ b/wrapper/CSharp/wolfTPM-tests.cs @@ -1,3 +1,26 @@ +/* wolfTPM-tests.cs + * + * Copyright (C) 2006-2022 wolfSSL Inc. + * + * This file is part of wolfTPM. + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Tests for C# wrapper using NUnit */ + using NUnit.Framework; using System; using System.IO; @@ -82,7 +105,7 @@ namespace tpm_csharp_test Console.WriteLine(sb.ToString()); } - void getSRK(Key srkKey, string auth) + private void GetSRK(Key srkKey, string auth) { int ret = device.CreateSRK(srkKey, (int)TPM2_Alg.RSA, @@ -90,66 +113,7 @@ namespace tpm_csharp_test Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); } - [SetUp] - public void TestInit() - { - parent_key = new Key(); - getSRK(parent_key, "ThisIsMyStorageKeyAuth"); - } - - [TearDown] - public void TestCleanup() - { - int ret = (int)Status.TPM_RC_SUCCESS; - - ret = device.UnloadHandle(parent_key); - Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); - } - - [Test] - public void TrySelfTest() - { - uint ret = (uint)device.SelfTest(); - Assert.That(ret, Is.EqualTo((uint)Status.TPM_RC_SUCCESS) | Is.EqualTo(0x80280400)); - } - - [Test] - public void TryFillBufferWithRandom() - { - const int bufSz = 256; - byte[] buf = new byte[bufSz]; - int ret = device.GetRandom(buf); - Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); - PrintByteArray(buf); - - Assert.That(buf, Has.Some.GreaterThan(0)); - } - - [Test] - public void TryGenerateAndLoadRSA() - { - GenerateRSA(); - LoadGeneratedRSA(); - } - - [Test] - public void TryGenerateAndLoadAES() - { - GenerateAES(); - LoadGeneratedAES(); - } - - void GenerateRSA() - { - GenerateKey("RSA"); - } - - void GenerateAES() - { - GenerateKey("AES"); - } - - void GenerateKey(string algorithm) + private void GenerateKey(string algorithm) { int ret = (int)Status.TPM_RC_SUCCESS; KeyBlob blob = new KeyBlob(); @@ -185,7 +149,6 @@ namespace tpm_csharp_test Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); ret = blob.GetKeyBlobAsBuffer(blob_buffer); - if (ret > 0) { Array.Resize(ref blob_buffer, ret); @@ -199,7 +162,7 @@ namespace tpm_csharp_test } else { - Console.WriteLine("Unexpected algorithm name!!!"); + Console.WriteLine("Unexpected algorithm name!"); return; } ret = (int)Status.TPM_RC_SUCCESS; @@ -210,24 +173,11 @@ namespace tpm_csharp_test ret = -1; } - ret = device.UnloadHandle(blob); Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); - } - - void LoadGeneratedRSA() - { - LoadGeneratedKey("RSA"); - } - - void LoadGeneratedAES() - { - LoadGeneratedKey("AES"); - } - - void LoadGeneratedKey(string algorithm) + private void LoadGeneratedKey(string algorithm) { int ret = (int)Status.TPM_RC_SUCCESS; KeyBlob blob = new KeyBlob(); @@ -243,7 +193,7 @@ namespace tpm_csharp_test } else { - Console.WriteLine("Unexpected algorithm name!!!"); + Console.WriteLine("Unexpected algorithm name!"); return; } @@ -255,13 +205,84 @@ namespace tpm_csharp_test ret = device.UnloadHandle(blob); Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); + } + + [SetUp] + public void TestInit() + { + parent_key = new Key(); + GetSRK(parent_key, "ThisIsMyStorageKeyAuth"); + } + + [TearDown] + public void TestCleanup() + { + int ret = device.UnloadHandle(parent_key); + Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); + } + + [Test] + public void TrySelfTest() + { + uint ret = (uint)device.SelfTest(); + Assert.That(ret, Is.EqualTo((uint)Status.TPM_RC_SUCCESS) | + Is.EqualTo(0x80280400)); + } + + [Test] + public void TryFillBufferWithRandom() + { + int ret; + const int bufSz = 256; + byte[] buf = new byte[bufSz]; + + ret = device.GetRandom(buf); + Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); + PrintByteArray(buf); + + Assert.That(buf, Has.Some.GreaterThan(0)); + } + + [Test] + public void TryGenerateAndLoadRSA() + { + GenerateKey("RSA"); + LoadGeneratedKey("RSA"); + } + + [Test] + public void TryGenerateAndLoadAES() + { + GenerateKey("AES"); + LoadGeneratedKey("AES"); + } + + [Test] + public void TryAuthSession() + { + int ret; + Session tpmSession = new Session(); + const int bufSz = 256; + byte[] buf = new byte[bufSz]; + + Console.WriteLine("Testing Parameter Encryption with AES CFB"); + + ret = tpmSession.StartAuth(device, parent_key, TPM2_Alg.CFB); + Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); + + /* Do sensitive operation */ + ret = device.GetRandom(buf); + Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); + + ret = tpmSession.StopAuth(device); + Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); } [Test] public void TryLoadRSAPublicKey() { - int ret = (int)Status.TPM_RC_SUCCESS; + int ret; Key pub_key; int exp = 0x10001; @@ -279,8 +300,7 @@ namespace tpm_csharp_test [Test] public void TryLoadRSAPrivateKey() { - int ret = (int)Status.TPM_RC_SUCCESS; - + int ret; Key priv_key; int exp = 0x10001; @@ -301,7 +321,7 @@ namespace tpm_csharp_test [Test] public void TryImportRSAPrivateKey() { - int ret = (int)Status.TPM_RC_SUCCESS; + int ret; KeyBlob blob; int exp = 0x10001; @@ -319,7 +339,6 @@ namespace tpm_csharp_test ret = device.UnloadHandle(blob); Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret); - } } diff --git a/wrapper/CSharp/wolfTPM.cs b/wrapper/CSharp/wolfTPM.cs index c0e0701..9eda1ac 100644 --- a/wrapper/CSharp/wolfTPM.cs +++ b/wrapper/CSharp/wolfTPM.cs @@ -1,3 +1,24 @@ +/* wolfTPM.cs + * + * Copyright (C) 2006-2022 wolfSSL Inc. + * + * This file is part of wolfTPM. + * + * wolfTPM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfTPM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + using System; using System.Runtime.InteropServices; @@ -7,6 +28,7 @@ namespace wolfTPM public enum Status : int { TPM_RC_SUCCESS = 0, + BAD_FUNC_ARG = -173, } public enum TPM2_Object : ulong @@ -99,6 +121,11 @@ namespace wolfTPM [DllImport(DLLNAME, EntryPoint = "wolfTPM2_SetKeyBlobFromBuffer")] private static extern int wolfTPM2_SetKeyBlobFromBuffer(IntPtr key, byte[] buffer, int bufferSz); + + + [DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetHandleRefFromKeyBlob")] + private static extern IntPtr wolfTPM2_GetHandleRefFromKeyBlob(IntPtr keyBlob); + internal IntPtr keyblob; public KeyBlob() @@ -124,6 +151,11 @@ namespace wolfTPM { return wolfTPM2_SetKeyBlobFromBuffer(keyblob, buffer, buffer.Length); } + + public IntPtr GetHandle() + { + return wolfTPM2_GetHandleRefFromKeyBlob(keyblob); + } } public class Key @@ -140,7 +172,6 @@ namespace wolfTPM /* Native Getters and Setters */ /* ================================================================== */ - [DllImport(DLLNAME, EntryPoint = "wolfTPM2_SetKeyAuthPassword")] private static extern int wolfTPM2_SetKeyAuthPassword( IntPtr key, @@ -166,6 +197,12 @@ namespace wolfTPM } } + public IntPtr GetHandle() + { + return wolfTPM2_GetHandleRefFromKey(key); + } + + /* kept for backwards compatibility, use GetHandle */ public IntPtr GetHandleRefFromKey() { return wolfTPM2_GetHandleRefFromKey(key); @@ -228,7 +265,6 @@ namespace wolfTPM isDecrypt ? 1 : 0); } - } public class Session @@ -241,23 +277,76 @@ namespace wolfTPM [DllImport(DLLNAME, EntryPoint = "wolfTPM2_FreeSession")] private static extern int wolfTPM2_FreeSession(IntPtr session); + [DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetHandleRefFromSession")] + private static extern IntPtr wolfTPM2_GetHandleRefFromSession(IntPtr session); internal IntPtr session; + internal int sessionIdx; public Session() { session = wolfTPM2_NewSession(); + sessionIdx = 1; /* for most commands the index is 1 */ + } + + public Session(int index) + { + session = wolfTPM2_NewSession(); + sessionIdx = index; } ~Session() { if (session != IntPtr.Zero) { - // TODO: check return value + /* ignore return code on free */ wolfTPM2_FreeSession(session); } } + public IntPtr GetHandle() + { + return wolfTPM2_GetHandleRefFromSession(session); + } + + public int StartAuth(Device device, Key parentKey, TPM2_Alg algMode) + { + int ret; + + /* Algorithm modes: With parameter encryption use CFB or XOR. + * For HMAC only (no parameter encryption) use NULL. */ + if (algMode != TPM2_Alg.NULL && + algMode != TPM2_Alg.CFB && + algMode != TPM2_Alg.XOR) { + return (int)Status.BAD_FUNC_ARG; + } + + /* Start an authenticated session (salted / unbound) with + * parameter encryption */ + ret = device.StartSession(this, parentKey, IntPtr.Zero, + (byte)SE.HMAC, (int)algMode); + if (ret == (int)Status.TPM_RC_SUCCESS) { + /* Set session for authorization of the primary key */ + ret = device.SetAuthSession(this, this.sessionIdx, + (byte)(SESSION_mask.decrypt | SESSION_mask.encrypt | + SESSION_mask.continueSession)); + } + + return ret; + } + + public int StopAuth(Device device) + { + int ret; + + /* Clear the auth index, since the auth session is ending */ + device.ClearAuthSession(this, this.sessionIdx); + + /* Unload session */ + ret = device.UnloadHandle(this); + + return ret; + } } public class Device @@ -330,24 +419,24 @@ namespace wolfTPM } [DllImport(DLLNAME, EntryPoint = "wolfTPM2_StartSession")] - private static extern int wolfTPM2_StartSession(IntPtr dev, + private static extern int wolfTPM2_StartSession(IntPtr dev, IntPtr session, IntPtr tmpKey, IntPtr bind, byte sesType, int encDecAlg); - public int StartSession(IntPtr session, + public int StartSession(Session tpmSession, Key tmpKey, IntPtr bind, byte sesType, int encDecAlg) { return wolfTPM2_StartSession(device, - session, - tmpKey.key, - bind, - sesType, - encDecAlg); + tpmSession.session, + tmpKey.key, + bind, + sesType, + encDecAlg); } [DllImport(DLLNAME, EntryPoint = "wolfTPM2_SetAuthSession")] @@ -355,14 +444,26 @@ namespace wolfTPM int index, IntPtr tpmSession, byte sessionAttributes); - public int SetAuthSession(IntPtr session, + public int SetAuthSession(Session tpmSession, int index, byte sessionAttributes) { /* For sessionAttributes suggest using: * (byte)(SESSION_mask.decrypt | SESSION_mask.encrypt | SESSION_mask.continueSession) */ - return wolfTPM2_SetAuthSession(device, index, session, sessionAttributes); + return wolfTPM2_SetAuthSession(device, + index, + tpmSession.session, + sessionAttributes); + } + + public int ClearAuthSession(Session tpmSession, + int index) + { + return wolfTPM2_SetAuthSession(device, + index, + IntPtr.Zero, + 0); } @@ -394,7 +495,7 @@ namespace wolfTPM { return wolfTPM2_CreateKey(device, keyBlob.keyblob, - parent.GetHandleRefFromKey(), + parent.GetHandle(), publicTemplate.template, auth, auth.Length); @@ -408,7 +509,7 @@ namespace wolfTPM public int LoadKey(KeyBlob keyBlob, Key parent) { - return wolfTPM2_LoadKey(device, keyBlob.keyblob, parent.GetHandleRefFromKey()); + return wolfTPM2_LoadKey(device, keyBlob.keyblob, parent.GetHandle()); } @@ -417,7 +518,7 @@ namespace wolfTPM IntPtr primaryHandle, IntPtr key, IntPtr persistentHandle); public int StoreKey(Key key, IntPtr primaryHandle, IntPtr persistentHandle) { - return wolfTPM2_NVStoreKey(device, primaryHandle, key.GetHandleRefFromKey(), + return wolfTPM2_NVStoreKey(device, primaryHandle, key.GetHandle(), persistentHandle); } @@ -506,14 +607,18 @@ namespace wolfTPM private static extern int wolfTPM2_UnloadHandle(IntPtr dev, IntPtr handle); public int UnloadHandle(Key key) { - return wolfTPM2_UnloadHandle(device, key.key); + return wolfTPM2_UnloadHandle(device, key.GetHandle()); } - public int UnloadHandle(KeyBlob keyblob) + public int UnloadHandle(KeyBlob keyBlob) { - return wolfTPM2_UnloadHandle(device, keyblob.keyblob); + return wolfTPM2_UnloadHandle(device, keyBlob.GetHandle()); } + public int UnloadHandle(Session tpmSession) + { + return wolfTPM2_UnloadHandle(device, tpmSession.GetHandle()); + } } }