mirror of https://github.com/wolfSSL/wolfTPM.git
Adding a C# wrapper
Tested with swtpm (linux and mono) and on Windows (Visual studio project and TBS) Co-authored-by: Anthony Hu <anthony@wolfssl.com>pull/203/head
parent
efc85dfbfb
commit
3ebc1fc936
|
@ -39,6 +39,7 @@ include IDE/include.am
|
|||
include certs/include.am
|
||||
include tests/include.am
|
||||
include docs/include.am
|
||||
include wrapper/include.am
|
||||
|
||||
EXTRA_DIST+= README.md
|
||||
EXTRA_DIST+= ChangeLog.md
|
||||
|
|
|
@ -173,7 +173,7 @@ int TPM2_KDFa(
|
|||
copyLen = keySz - pos;
|
||||
}
|
||||
|
||||
memcpy(keyStream, hash, copyLen);
|
||||
XMEMCPY(keyStream, hash, copyLen);
|
||||
keyStream += copyLen;
|
||||
}
|
||||
ret = keySz;
|
||||
|
|
266
src/tpm2_wrap.c
266
src/tpm2_wrap.c
|
@ -172,6 +172,272 @@ int wolfTPM2_Init(WOLFTPM2_DEV* dev, TPM2HalIoCb ioCb, void* userCtx)
|
|||
return rc;
|
||||
}
|
||||
|
||||
#ifndef WOLFTPM2_NO_HEAP
|
||||
WOLFTPM2_DEV *wolfTPM2_New(void)
|
||||
{
|
||||
WOLFTPM2_DEV *dev = NULL;
|
||||
|
||||
dev = (WOLFTPM2_DEV *) XMALLOC(sizeof(WOLFTPM2_DEV), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (dev == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wolfTPM2_Init(dev, NULL, NULL) != TPM_RC_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
int wolfTPM2_Free(WOLFTPM2_DEV *dev)
|
||||
{
|
||||
if (dev != NULL) {
|
||||
wolfTPM2_Cleanup(dev);
|
||||
XFREE(dev, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
WOLFTPM2_KEYBLOB* wolfTPM2_GetNewKeyBlob(void)
|
||||
{
|
||||
WOLFTPM2_KEYBLOB* blob = NULL;
|
||||
|
||||
blob = (WOLFTPM2_KEYBLOB *) XMALLOC(sizeof(WOLFTPM2_KEYBLOB), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (blob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XMEMSET(blob, 0, sizeof(WOLFTPM2_KEYBLOB));
|
||||
return blob;
|
||||
}
|
||||
|
||||
int wolfTPM2_CleanupKeyBlob(WOLFTPM2_KEYBLOB* blob)
|
||||
{
|
||||
if (blob != NULL) {
|
||||
XFREE(blob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
WOLFTPM_API TPMT_PUBLIC* wolfTPM2_GetNewPublicTemplate(void)
|
||||
{
|
||||
TPMT_PUBLIC* template = NULL;
|
||||
|
||||
template = (TPMT_PUBLIC *) XMALLOC(sizeof(TPMT_PUBLIC), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (template == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XMEMSET(template, 0, sizeof(TPMT_PUBLIC));
|
||||
return template;
|
||||
}
|
||||
|
||||
WOLFTPM_API int wolfTPM2_CleanupPublicTemplate(TPMT_PUBLIC* template)
|
||||
{
|
||||
if (template != NULL) {
|
||||
XFREE(template, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
WOLFTPM_API WOLFTPM2_KEY* wolfTPM2_GetNewKey(void)
|
||||
{
|
||||
WOLFTPM2_KEY* key = NULL;
|
||||
|
||||
key = (WOLFTPM2_KEY *) XMALLOC(sizeof(WOLFTPM2_KEY), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (key == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XMEMSET(key, 0, sizeof(WOLFTPM2_KEY));
|
||||
return key;
|
||||
}
|
||||
|
||||
WOLFTPM_API int wolfTPM2_CleanupKey(WOLFTPM2_KEY* key)
|
||||
{
|
||||
if (key != NULL) {
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
WOLFTPM2_SESSION* wolfTPM2_GetNewSession(void)
|
||||
{
|
||||
WOLFTPM2_SESSION* session = NULL;
|
||||
|
||||
session = (WOLFTPM2_SESSION *) XMALLOC(sizeof(WOLFTPM2_SESSION), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (session == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XMEMSET(session, 0, sizeof(WOLFTPM2_SESSION));
|
||||
return session;
|
||||
}
|
||||
|
||||
int wolfTPM2_CleanupSession(WOLFTPM2_SESSION* session)
|
||||
{
|
||||
if (session != NULL) {
|
||||
XFREE(session, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
#endif /* WOLFTPM2_NO_HEAP */
|
||||
|
||||
WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromKey(WOLFTPM2_KEY* key)
|
||||
{
|
||||
if (key == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return &(key->handle);
|
||||
}
|
||||
|
||||
int wolfTPM2_GetKeyBlobAsBuffer(byte *buffer, word32 bufferSz,
|
||||
WOLFTPM2_KEYBLOB* key)
|
||||
{
|
||||
int rc = 0;
|
||||
int sz = 0;
|
||||
byte pubAreaBuffer[sizeof(TPM2B_PUBLIC)];
|
||||
int pubAreaSize;
|
||||
|
||||
if ((buffer == NULL) || (bufferSz <= 0) || (key == NULL)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* publicArea is encoded format. Eliminates empty fields, saves space. */
|
||||
rc = TPM2_AppendPublic(pubAreaBuffer, (word32)sizeof(pubAreaBuffer),
|
||||
&pubAreaSize, &key->pub);
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (pubAreaSize != (key->pub.size + (int)sizeof(key->pub.size))) {
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
printf("Sanity check for publicArea size failed\n");
|
||||
#endif
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
if (bufferSz < sizeof(key->pub.size) + sizeof(UINT16) + key->pub.size +
|
||||
sizeof(UINT16) + key->priv.size) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* Write size marker for the public part */
|
||||
XMEMCPY(buffer + sz, &key->pub.size, sizeof(key->pub.size));
|
||||
sz += sizeof(key->pub.size);
|
||||
|
||||
/* Write the public part with bytes aligned */
|
||||
XMEMCPY(buffer + sz, pubAreaBuffer, sizeof(UINT16) + key->pub.size);
|
||||
sz += sizeof(UINT16) + key->pub.size;
|
||||
|
||||
/* Write the private part, size marker is included */
|
||||
XMEMCPY(buffer + sz, &key->priv, sizeof(UINT16) + key->priv.size);
|
||||
sz += sizeof(UINT16) + key->priv.size;
|
||||
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
TPM2_PrintBin(buffer, sz);
|
||||
printf("Getting %d bytes\n", (int)sz);
|
||||
#endif
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
int wolfTPM2_SetKeyBlobFromBuffer(WOLFTPM2_KEYBLOB* key, byte *buffer,
|
||||
word32 bufferSz)
|
||||
{
|
||||
int rc = 0;
|
||||
byte pubAreaBuffer[sizeof(TPM2B_PUBLIC)];
|
||||
int pubAreaSize;
|
||||
byte *runner = buffer;
|
||||
size_t done_reading = 0;
|
||||
|
||||
if ((key == NULL) || (buffer == NULL) || (bufferSz <= 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMSET(key, 0, sizeof(WOLFTPM2_KEYBLOB));
|
||||
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
TPM2_PrintBin(buffer, bufferSz);
|
||||
printf("Setting %d bytes\n", (int)bufferSz);
|
||||
#endif
|
||||
|
||||
if (bufferSz < done_reading + sizeof(key->pub.size)) {
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
printf("Buffer size check failed (%d)\n", bufferSz);
|
||||
#endif
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
XMEMCPY(&key->pub.size, runner, sizeof(key->pub.size));
|
||||
runner += sizeof(key->pub.size);
|
||||
done_reading += sizeof(key->pub.size);
|
||||
|
||||
if (bufferSz < done_reading + sizeof(UINT16) + key->pub.size) {
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
printf("Buffer size check failed (%d)\n", bufferSz);
|
||||
#endif
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
XMEMCPY(pubAreaBuffer, runner, sizeof(UINT16) + key->pub.size);
|
||||
runner += sizeof(UINT16) + key->pub.size;
|
||||
done_reading += sizeof(UINT16) + key->pub.size;
|
||||
|
||||
/* Decode the byte stream into a publicArea structure ready for use */
|
||||
rc = TPM2_ParsePublic(&key->pub, pubAreaBuffer,
|
||||
(word32)sizeof(pubAreaBuffer), &pubAreaSize);
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (bufferSz < done_reading + sizeof(key->priv.size)) {
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
printf("Buffer size check failed (%d)\n", bufferSz);
|
||||
#endif
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
XMEMCPY(&key->priv.size, runner, sizeof(key->priv.size));
|
||||
runner += sizeof(key->priv.size);
|
||||
done_reading += sizeof(key->priv.size);
|
||||
|
||||
if (bufferSz < done_reading + key->priv.size) {
|
||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||
printf("Buffer size check failed (%d)\n", bufferSz);
|
||||
#endif
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
XMEMCPY(key->priv.buffer, runner, key->priv.size);
|
||||
runner += key->priv.size;
|
||||
done_reading += key->priv.size;
|
||||
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
int wolfTPM2_SetKeyAuthPassword(WOLFTPM2_KEY *key, const byte* auth,
|
||||
int authSz)
|
||||
{
|
||||
if ((key == NULL) || (authSz < 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if ((auth != NULL) && (authSz == 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* specify auth password for storage key */
|
||||
key->handle.auth.size = authSz;
|
||||
XMEMCPY(key->handle.auth.buffer, auth, authSz);
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
/* Access already started TPM module */
|
||||
int wolfTPM2_OpenExisting(WOLFTPM2_DEV* dev, TPM2HalIoCb ioCb, void* userCtx)
|
||||
{
|
||||
|
|
|
@ -569,8 +569,8 @@ WOLFTPM_API int wolfTPM2_ChangeAuthKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
|
|||
\sa wolfTPM2_CreatePrimaryKey
|
||||
*/
|
||||
WOLFTPM_API int wolfTPM2_CreateKey(WOLFTPM2_DEV* dev,
|
||||
WOLFTPM2_KEYBLOB* keyBlob, WOLFTPM2_HANDLE* parent, TPMT_PUBLIC* publicTemplate,
|
||||
const byte* auth, int authSz);
|
||||
WOLFTPM2_KEYBLOB* keyBlob, WOLFTPM2_HANDLE* parent,
|
||||
TPMT_PUBLIC* publicTemplate, const byte* auth, int authSz);
|
||||
|
||||
/*!
|
||||
\ingroup wolfTPM2_Wrappers
|
||||
|
@ -2348,6 +2348,28 @@ WOLFTPM_API int wolfTPM2_ClearCryptoDevCb(WOLFTPM2_DEV* dev, int devId);
|
|||
|
||||
#endif /* WOLF_CRYPTO_CB */
|
||||
|
||||
#ifndef WOLFTPM2_NO_HEAP
|
||||
WOLFTPM_API WOLFTPM2_DEV *wolfTPM2_New(void);
|
||||
WOLFTPM_API int wolfTPM2_Free(WOLFTPM2_DEV *dev);
|
||||
WOLFTPM_API WOLFTPM2_KEYBLOB* wolfTPM2_GetNewKeyBlob(void);
|
||||
WOLFTPM_API int wolfTPM2_CleanupKeyBlob(WOLFTPM2_KEYBLOB* blob);
|
||||
WOLFTPM_API TPMT_PUBLIC* wolfTPM2_GetNewPublicTemplate(void);
|
||||
WOLFTPM_API int wolfTPM2_CleanupPublicTemplate(TPMT_PUBLIC* template);
|
||||
WOLFTPM_API WOLFTPM2_KEY* wolfTPM2_GetNewKey(void);
|
||||
WOLFTPM_API int wolfTPM2_CleanupKey(WOLFTPM2_KEY* key);
|
||||
WOLFTPM_API WOLFTPM2_SESSION* wolfTPM2_GetNewSession(void);
|
||||
WOLFTPM_API int wolfTPM2_CleanupSession(WOLFTPM2_SESSION* session);
|
||||
#endif
|
||||
|
||||
WOLFTPM_API int wolfTPM2_OpenExistingDev(WOLFTPM2_DEV* dev);
|
||||
WOLFTPM_API WOLFTPM2_HANDLE* wolfTPM2_GetHandleRefFromKey(WOLFTPM2_KEY* key);
|
||||
WOLFTPM_API int wolfTPM2_SetKeyAuthPassword(WOLFTPM2_KEY *key, const byte* auth,
|
||||
int authSz);
|
||||
WOLFTPM_API int wolfTPM2_GetKeyBlobAsBuffer(byte *buffer, word32 bufferSz,
|
||||
WOLFTPM2_KEYBLOB* key);
|
||||
WOLFTPM_API int wolfTPM2_SetKeyBlobFromBuffer(WOLFTPM2_KEYBLOB* key,
|
||||
byte *buffer, word32 bufferSz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RunSettings>
|
||||
<RunConfiguration>
|
||||
<EnvironmentVariables>
|
||||
<!-- update to path to local vcpkg install
|
||||
<PATH>%PATH%;c:\vcpkg\installed\x64-windows\bin</PATH>
|
||||
-->
|
||||
<!--
|
||||
if wolfTPM cmake solution is built using visual studio,
|
||||
we need to back out several(5) directories `wrapper\CSharp\bin\Debug\netcoreapp3.1`
|
||||
-->
|
||||
<PATH>%PATH%;..\..\..\..\..\out\build\x64-Debug\bin</PATH>
|
||||
</EnvironmentVariables>
|
||||
</RunConfiguration>
|
||||
</RunSettings>
|
|
@ -0,0 +1,75 @@
|
|||
# wolfTPM (TPM 2.0) CSharp Wrappers
|
||||
|
||||
This directory contains the CSharp wrapper for the TPM 2.0 API wrapper API.
|
||||
|
||||
|
||||
Once you have created the simulator, you can should build wolfssl as described
|
||||
in the README.md in the root of this repo. Then you can build wolfTPM:
|
||||
|
||||
## Windows
|
||||
|
||||
A Visual Studio solution is provided. This will allow you to build the
|
||||
wrappers. In order to run the tests you will need to update the
|
||||
`.runsettings` to add the location of the `wolftpm.dll`. There is a
|
||||
placeholder to leverage a vcpkg build, but cmake can also be used to
|
||||
build wolfTPM with Visual Studios.
|
||||
|
||||
## Linux
|
||||
|
||||
The wrapper has been tested with the swtpm TCP protocol for use with
|
||||
the simulator. Please follow instructions in the `docs/SWTPM.md` file
|
||||
for building and running the simulator.
|
||||
|
||||
|
||||
```
|
||||
./autogen.sh
|
||||
./configure --enable-swtpm
|
||||
make all
|
||||
make check
|
||||
```
|
||||
|
||||
Prerequisites for linux
|
||||
|
||||
```
|
||||
apt install mono-tools-devel nunit
|
||||
```
|
||||
|
||||
You can then build and run the test wolfTPM:
|
||||
|
||||
```
|
||||
cd wrapper/CSharp
|
||||
mcs wolfTPM.cs wolfTPM-tests.cs -r:/usr/lib/cli/nunit.framework-2.6.3/nunit.framework.dll -t:library
|
||||
# run selftest case
|
||||
LD_LIBRARY_PATH=../../src/.libs/ nunit-console wolfTPM.dll -run=tpm_csharp_test.WolfTPMTest.TrySelfTest
|
||||
#run all tests
|
||||
LD_LIBRARY_PATH=../../src/.libs/ nunit-console wolfTPM.dll
|
||||
```
|
||||
|
||||
|
||||
You should see something similar to the following output:
|
||||
|
||||
```
|
||||
NUnit-Console version 2.6.4.0
|
||||
Copyright (C) 2002-2012 Charlie Poole.
|
||||
Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.
|
||||
Copyright (C) 2000-2002 Philip Craig.
|
||||
All Rights Reserved.
|
||||
|
||||
Runtime Environment -
|
||||
OS Version: Unix 5.13.0.40
|
||||
CLR Version: 4.0.30319.42000 ( Mono 4.0 ( 6.8.0.105 (Debian 6.8.0.105+dfsg-2 Wed Feb 26 23:23:50 UTC 2020) ) )
|
||||
|
||||
ProcessModel: Default DomainUsage: Single
|
||||
Execution Runtime: mono-4.0
|
||||
Selected test(s): tpm_csharp_test.WolfTPMTest.TryFillBufferWithRandom
|
||||
.wolfSSL Entering wolfCrypt_Init
|
||||
wolfSSL Entering wolfCrypt_Cleanup
|
||||
buf: { 44, 95, 206, 69, 252, 157, 173, 149, 26, 160, 21, 5, 35, 19, 255, 29, 251, 228, 206, 36, 77, 79, 160, 42, 25, 172, 82, 172, 152, 143, 179, 147, 52, 211, 238, 63, 34, 227, 243, 155, 17, 77, 135, 233, 103, 39, 211, 180, 55, 54, 36, 180, 87, 168, 28, 143, 104, 175, 176, 156, 154, 8, 114, 143, 123, 99, 110, 247, 46, 193, 93, 54, 208, 128, 162, 190, 225, 255, 109, 44, 8, 153, 21, 162, 139, 70, 7, 73, 13, 145, 157, 111, 20, 151, 101, 44, 45, 154, 159, 139, 153, 48, 117, 69, 179, 186, 48, 225, 20, 145, 120, 78, 58, 228, 4, 146, 241, 195, 121, 94, 44, 92, 246, 198, 71, 122, 176, 133, 21, 27, 41, 17, 7, 96, 122, 155, 105, 57, 150, 45, 63, 165, 136, 195, 173, 160, 137, 136, 207, 19, 60, 140, 2, 203, 246, 248, 179, 170, 203, 153, 154, 229, 104, 200, 141, 94, 139, 25, 103, 235, 116, 97, 186, 29, 32, 133, 205, 122, 230, 51, 88, 195, 69, 158, 199, 255, 212, 117, 3, 110, 201, 179, 138, 242, 172, 160, 121, 46, 117, 41, 185, 11, 22, 99, 4, 214, 37, 179, 246, 71, 146, 168, 116, 28, 146, 221, 53, 21, 5, 18, 84, 57, 137, 171, 237, 233, 215, 91, 88, 4, 205, 207, 218, 74, 46, 105, 106, 55, 254, 211, 186, 151, 136, 81, 128, 33, 77, 218, 203, 19, 164, 76, 177, 2, 185, 212, } (256 bytes)
|
||||
|
||||
Tests run: 1, Errors: 0, Failures: 0, Inconclusive: 0, Time: 0.0747956 seconds
|
||||
Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0
|
||||
```
|
||||
|
||||
If you run this multiple time, you will see the content of the buffer changing
|
||||
for each execution.
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# vim:ft=automake
|
||||
# All paths should be given relative to the root
|
||||
|
||||
wrapper_CSharpdir = $(wrapperdir)/CSharp
|
||||
|
||||
dist_wrapper_CSharp_DATA= \
|
||||
wrapper/CSharp/README.md \
|
||||
wrapper/CSharp/wolfTPM.cs \
|
||||
wrapper/CSharp/wolfTPM-tests.cs \
|
||||
wrapper/CSharp/.runsettings \
|
||||
wrapper/CSharp/wolfTPM-csharp.csproj
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>wolfTPM_csharp</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,326 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using wolfTPM;
|
||||
|
||||
namespace tpm_csharp_test
|
||||
{
|
||||
[TestFixture]
|
||||
public class WolfTPMTest
|
||||
{
|
||||
/* Globals used for setup and teardown */
|
||||
private Device device = new Device();
|
||||
private Key parent_key;
|
||||
private static byte[] priv_buffer = {
|
||||
0xd5, 0x38, 0x1b, 0xc3, 0x8f, 0xc5, 0x93, 0x0c,
|
||||
0x47, 0x0b, 0x6f, 0x35, 0x92, 0xc5, 0xb0, 0x8d,
|
||||
0x46, 0xc8, 0x92, 0x18, 0x8f, 0xf5, 0x80, 0x0a,
|
||||
0xf7, 0xef, 0xa1, 0xfe, 0x80, 0xb9, 0xb5, 0x2a,
|
||||
0xba, 0xca, 0x18, 0xb0, 0x5d, 0xa5, 0x07, 0xd0,
|
||||
0x93, 0x8d, 0xd8, 0x9c, 0x04, 0x1c, 0xd4, 0x62,
|
||||
0x8e, 0xa6, 0x26, 0x81, 0x01, 0xff, 0xce, 0x8a,
|
||||
0x2a, 0x63, 0x34, 0x35, 0x40, 0xaa, 0x6d, 0x80,
|
||||
0xde, 0x89, 0x23, 0x6a, 0x57, 0x4d, 0x9e, 0x6e,
|
||||
0xad, 0x93, 0x4e, 0x56, 0x90, 0x0b, 0x6d, 0x9d,
|
||||
0x73, 0x8b, 0x0c, 0xae, 0x27, 0x3d, 0xde, 0x4e,
|
||||
0xf0, 0xaa, 0xc5, 0x6c, 0x78, 0x67, 0x6c, 0x94,
|
||||
0x52, 0x9c, 0x37, 0x67, 0x6c, 0x2d, 0xef, 0xbb,
|
||||
0xaf, 0xdf, 0xa6, 0x90, 0x3c, 0xc4, 0x47, 0xcf,
|
||||
0x8d, 0x96, 0x9e, 0x98, 0xa9, 0xb4, 0x9f, 0xc5,
|
||||
0xa6, 0x50, 0xdc, 0xb3, 0xf0, 0xfb, 0x74, 0x17
|
||||
};
|
||||
|
||||
private static byte[] pub_buffer = {
|
||||
0xc3, 0x03, 0xd1, 0x2b, 0xfe, 0x39, 0xa4, 0x32,
|
||||
0x45, 0x3b, 0x53, 0xc8, 0x84, 0x2b, 0x2a, 0x7c,
|
||||
0x74, 0x9a, 0xbd, 0xaa, 0x2a, 0x52, 0x07, 0x47,
|
||||
0xd6, 0xa6, 0x36, 0xb2, 0x07, 0x32, 0x8e, 0xd0,
|
||||
0xba, 0x69, 0x7b, 0xc6, 0xc3, 0x44, 0x9e, 0xd4,
|
||||
0x81, 0x48, 0xfd, 0x2d, 0x68, 0xa2, 0x8b, 0x67,
|
||||
0xbb, 0xa1, 0x75, 0xc8, 0x36, 0x2c, 0x4a, 0xd2,
|
||||
0x1b, 0xf7, 0x8b, 0xba, 0xcf, 0x0d, 0xf9, 0xef,
|
||||
0xec, 0xf1, 0x81, 0x1e, 0x7b, 0x9b, 0x03, 0x47,
|
||||
0x9a, 0xbf, 0x65, 0xcc, 0x7f, 0x65, 0x24, 0x69,
|
||||
0xa6, 0xe8, 0x14, 0x89, 0x5b, 0xe4, 0x34, 0xf7,
|
||||
0xc5, 0xb0, 0x14, 0x93, 0xf5, 0x67, 0x7b, 0x3a,
|
||||
0x7a, 0x78, 0xe1, 0x01, 0x56, 0x56, 0x91, 0xa6,
|
||||
0x13, 0x42, 0x8d, 0xd2, 0x3c, 0x40, 0x9c, 0x4c,
|
||||
0xef, 0xd1, 0x86, 0xdf, 0x37, 0x51, 0x1b, 0x0c,
|
||||
0xa1, 0x3b, 0xf5, 0xf1, 0xa3, 0x4a, 0x35, 0xe4,
|
||||
0xe1, 0xce, 0x96, 0xdf, 0x1b, 0x7e, 0xbf, 0x4e,
|
||||
0x97, 0xd0, 0x10, 0xe8, 0xa8, 0x08, 0x30, 0x81,
|
||||
0xaf, 0x20, 0x0b, 0x43, 0x14, 0xc5, 0x74, 0x67,
|
||||
0xb4, 0x32, 0x82, 0x6f, 0x8d, 0x86, 0xc2, 0x88,
|
||||
0x40, 0x99, 0x36, 0x83, 0xba, 0x1e, 0x40, 0x72,
|
||||
0x22, 0x17, 0xd7, 0x52, 0x65, 0x24, 0x73, 0xb0,
|
||||
0xce, 0xef, 0x19, 0xcd, 0xae, 0xff, 0x78, 0x6c,
|
||||
0x7b, 0xc0, 0x12, 0x03, 0xd4, 0x4e, 0x72, 0x0d,
|
||||
0x50, 0x6d, 0x3b, 0xa3, 0x3b, 0xa3, 0x99, 0x5e,
|
||||
0x9d, 0xc8, 0xd9, 0x0c, 0x85, 0xb3, 0xd9, 0x8a,
|
||||
0xd9, 0x54, 0x26, 0xdb, 0x6d, 0xfa, 0xac, 0xbb,
|
||||
0xff, 0x25, 0x4c, 0xc4, 0xd1, 0x79, 0xf4, 0x71,
|
||||
0xd3, 0x86, 0x40, 0x18, 0x13, 0xb0, 0x63, 0xb5,
|
||||
0x72, 0x4e, 0x30, 0xc4, 0x97, 0x84, 0x86, 0x2d,
|
||||
0x56, 0x2f, 0xd7, 0x15, 0xf7, 0x7f, 0xc0, 0xae,
|
||||
0xf5, 0xfc, 0x5b, 0xe5, 0xfb, 0xa1, 0xba, 0xd3
|
||||
};
|
||||
|
||||
private byte[] generatedAES;
|
||||
private byte[] generatedRSA;
|
||||
|
||||
private static void PrintByteArray(byte[] bytes)
|
||||
{
|
||||
var sb = new StringBuilder("buf: { ");
|
||||
foreach (var b in bytes)
|
||||
{
|
||||
sb.Append(b + ", ");
|
||||
}
|
||||
sb.Append("} (");
|
||||
sb.Append(bytes.Length);
|
||||
sb.Append(" bytes)");
|
||||
Console.WriteLine(sb.ToString());
|
||||
}
|
||||
|
||||
void getSRK(Key srkKey, string auth)
|
||||
{
|
||||
int ret = device.CreateSRK(srkKey,
|
||||
(int)TPM2_Alg.RSA,
|
||||
auth);
|
||||
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)
|
||||
{
|
||||
int ret = (int)Status.TPM_RC_SUCCESS;
|
||||
KeyBlob blob = new KeyBlob();
|
||||
Template template = new Template();
|
||||
byte[] blob_buffer = new byte[Device.MAX_KEYBLOB_BYTES];
|
||||
|
||||
if (algorithm == "RSA")
|
||||
{
|
||||
ret = template.GetKeyTemplate_RSA((ulong)(
|
||||
TPM2_Object.sensitiveDataOrigin |
|
||||
TPM2_Object.userWithAuth |
|
||||
TPM2_Object.decrypt |
|
||||
TPM2_Object.sign |
|
||||
TPM2_Object.noDA));
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
}
|
||||
else if (algorithm == "AES")
|
||||
{
|
||||
ret = template.GetKeyTemplate_Symmetric(256, TPM2_Alg.CTR, true, true);
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unexpected algorithm name!!!");
|
||||
Assert.Fail();
|
||||
}
|
||||
|
||||
ret = device.CreateKey(blob, parent_key, template,
|
||||
"ThisIsMyStorageKeyAuth");
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
|
||||
ret = device.LoadKey(blob, parent_key);
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
|
||||
ret = blob.GetKeyBlobAsBuffer(blob_buffer);
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
Array.Resize(ref blob_buffer, ret);
|
||||
if (algorithm == "RSA")
|
||||
{
|
||||
generatedRSA = blob_buffer;
|
||||
}
|
||||
else if (algorithm == "AES")
|
||||
{
|
||||
generatedAES = blob_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unexpected algorithm name!!!");
|
||||
return;
|
||||
}
|
||||
ret = (int)Status.TPM_RC_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("wolfTPM2_GetKeyBlobAsBuffer() failed.");
|
||||
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)
|
||||
{
|
||||
int ret = (int)Status.TPM_RC_SUCCESS;
|
||||
KeyBlob blob = new KeyBlob();
|
||||
byte[] blob_buffer;
|
||||
|
||||
if (algorithm == "RSA")
|
||||
{
|
||||
blob_buffer = generatedRSA;
|
||||
}
|
||||
else if (algorithm == "AES")
|
||||
{
|
||||
blob_buffer = generatedAES;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unexpected algorithm name!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = blob.SetKeyBlobFromBuffer(blob_buffer);
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
|
||||
ret = device.LoadKey(blob, parent_key);
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
|
||||
ret = device.UnloadHandle(blob);
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TryLoadRSAPublicKey()
|
||||
{
|
||||
int ret = (int)Status.TPM_RC_SUCCESS;
|
||||
Key pub_key;
|
||||
int exp = 0x10001;
|
||||
|
||||
PrintByteArray(pub_buffer);
|
||||
|
||||
pub_key = new Key();
|
||||
|
||||
ret = device.LoadRsaPublicKey(pub_key, pub_buffer, exp);
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
|
||||
ret = device.UnloadHandle(pub_key);
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TryLoadRSAPrivateKey()
|
||||
{
|
||||
int ret = (int)Status.TPM_RC_SUCCESS;
|
||||
|
||||
Key priv_key;
|
||||
int exp = 0x10001;
|
||||
|
||||
PrintByteArray(pub_buffer);
|
||||
PrintByteArray(priv_buffer);
|
||||
|
||||
priv_key = new Key();
|
||||
|
||||
ret = device.LoadRsaPrivateKey(parent_key, priv_key,
|
||||
pub_buffer, exp,
|
||||
priv_buffer);
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
|
||||
ret = device.UnloadHandle(priv_key);
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TryImportRSAPrivateKey()
|
||||
{
|
||||
int ret = (int)Status.TPM_RC_SUCCESS;
|
||||
|
||||
KeyBlob blob;
|
||||
int exp = 0x10001;
|
||||
|
||||
PrintByteArray(pub_buffer);
|
||||
PrintByteArray(priv_buffer);
|
||||
|
||||
blob = new KeyBlob();
|
||||
|
||||
ret = device.ImportRsaPrivateKey(parent_key, blob,
|
||||
pub_buffer,
|
||||
exp, priv_buffer,
|
||||
(uint)TPM2_Alg.NULL, (uint)TPM2_Alg.NULL);
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
|
||||
ret = device.UnloadHandle(blob);
|
||||
Assert.AreEqual((int)Status.TPM_RC_SUCCESS, ret);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,479 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace wolfTPM
|
||||
{
|
||||
|
||||
public enum Status : int
|
||||
{
|
||||
TPM_RC_SUCCESS = 0,
|
||||
}
|
||||
|
||||
public enum TPM2_Object : ulong
|
||||
{
|
||||
fixedTPM = 0x00000002,
|
||||
stClear = 0x00000004,
|
||||
fixedParent = 0x00000010,
|
||||
sensitiveDataOrigin = 0x00000020,
|
||||
userWithAuth = 0x00000040,
|
||||
adminWithPolicy = 0x00000080,
|
||||
derivedDataOrigin = 0x00000200,
|
||||
noDA = 0x00000400,
|
||||
encryptedDuplication = 0x00000800,
|
||||
restricted = 0x00010000,
|
||||
decrypt = 0x00020000,
|
||||
sign = 0x00040000,
|
||||
}
|
||||
|
||||
public enum TPM2_Alg : uint
|
||||
{
|
||||
ERROR = 0x0000,
|
||||
RSA = 0x0001,
|
||||
SHA = 0x0004,
|
||||
SHA1 = SHA,
|
||||
HMAC = 0x0005,
|
||||
AES = 0x0006,
|
||||
MGF1 = 0x0007,
|
||||
KEYEDHASH = 0x0008,
|
||||
XOR = 0x000A,
|
||||
SHA256 = 0x000B,
|
||||
SHA384 = 0x000C,
|
||||
SHA512 = 0x000D,
|
||||
NULL = 0x0010,
|
||||
SM3_256 = 0x0012,
|
||||
SM4 = 0x0013,
|
||||
RSASSA = 0x0014,
|
||||
RSAES = 0x0015,
|
||||
RSAPSS = 0x0016,
|
||||
OAEP = 0x0017,
|
||||
ECDSA = 0x0018,
|
||||
ECDH = 0x0019,
|
||||
ECDAA = 0x001A,
|
||||
SM2 = 0x001B,
|
||||
ECSCHNORR = 0x001C,
|
||||
ECMQV = 0x001D,
|
||||
KDF1_SP800_56A = 0x0020,
|
||||
KDF2 = 0x0021,
|
||||
KDF1_SP800_108 = 0x0022,
|
||||
ECC = 0x0023,
|
||||
SYMCIPHER = 0x0025,
|
||||
CAMELLIA = 0x0026,
|
||||
CTR = 0x0040,
|
||||
OFB = 0x0041,
|
||||
CBC = 0x0042,
|
||||
CFB = 0x0043,
|
||||
ECB = 0x0044,
|
||||
}
|
||||
|
||||
public enum SE : byte
|
||||
{
|
||||
HMAC = 0x00,
|
||||
POLICY = 0x01,
|
||||
TRIAL = 0x03,
|
||||
}
|
||||
|
||||
public class KeyBlob
|
||||
{
|
||||
const string DLLNAME = "wolftpm";
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetNewKeyBlob")]
|
||||
private static extern IntPtr wolfTPM2_GetNewKeyBlob();
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_CleanupKeyBlob")]
|
||||
private static extern int wolfTPM2_CleanupKeyBlob(IntPtr blob);
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetKeyBlobAsBuffer")]
|
||||
private static extern int wolfTPM2_GetKeyBlobAsBuffer(byte[] buffer,
|
||||
int bufferSz, IntPtr key);
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_SetKeyBlobFromBuffer")]
|
||||
private static extern int wolfTPM2_SetKeyBlobFromBuffer(IntPtr key,
|
||||
byte[] buffer, int bufferSz);
|
||||
internal IntPtr keyblob;
|
||||
|
||||
public KeyBlob()
|
||||
{
|
||||
keyblob = wolfTPM2_GetNewKeyBlob();
|
||||
}
|
||||
|
||||
~KeyBlob()
|
||||
{
|
||||
if (keyblob != IntPtr.Zero)
|
||||
{
|
||||
// TODO: check return value?
|
||||
wolfTPM2_CleanupKeyBlob(keyblob);
|
||||
}
|
||||
}
|
||||
|
||||
public int GetKeyBlobAsBuffer(byte[] buffer)
|
||||
{
|
||||
return wolfTPM2_GetKeyBlobAsBuffer(buffer, buffer.Length, keyblob);
|
||||
}
|
||||
|
||||
public int SetKeyBlobFromBuffer(byte[] buffer)
|
||||
{
|
||||
return wolfTPM2_SetKeyBlobFromBuffer(keyblob, buffer, buffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public class Key
|
||||
{
|
||||
const string DLLNAME = "wolftpm";
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetNewKey")]
|
||||
private static extern IntPtr wolfTPM2_GetNewKey();
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_CleanupKey")]
|
||||
private static extern int wolfTPM2_CleanupKey(IntPtr key);
|
||||
|
||||
/* ================================================================== */
|
||||
/* Native Getters and Setters */
|
||||
/* ================================================================== */
|
||||
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_SetKeyAuthPassword")]
|
||||
private static extern int wolfTPM2_SetKeyAuthPassword(
|
||||
IntPtr key,
|
||||
string auth,
|
||||
int authSz);
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetHandleRefFromKey")]
|
||||
private static extern IntPtr wolfTPM2_GetHandleRefFromKey(IntPtr key);
|
||||
|
||||
internal IntPtr key;
|
||||
|
||||
public Key()
|
||||
{
|
||||
key = wolfTPM2_GetNewKey();
|
||||
}
|
||||
|
||||
~Key()
|
||||
{
|
||||
if (key != IntPtr.Zero)
|
||||
{
|
||||
// TODO: check return value
|
||||
wolfTPM2_CleanupKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
public IntPtr GetHandleRefFromKey()
|
||||
{
|
||||
return wolfTPM2_GetHandleRefFromKey(key);
|
||||
}
|
||||
|
||||
public int SetKeyAuthPassword(string auth)
|
||||
{
|
||||
return wolfTPM2_SetKeyAuthPassword(key,
|
||||
auth,
|
||||
auth.Length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Template
|
||||
{
|
||||
const string DLLNAME = "wolftpm";
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetNewPublicTemplate")]
|
||||
private static extern IntPtr wolfTPM2_GetNewPublicTemplate();
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_CleanupPublicTemplate")]
|
||||
private static extern int wolfTPM2_CleanupPublicTemplate(IntPtr template);
|
||||
|
||||
internal IntPtr template;
|
||||
public Template()
|
||||
{
|
||||
template = wolfTPM2_GetNewPublicTemplate();
|
||||
}
|
||||
|
||||
~Template()
|
||||
{
|
||||
wolfTPM2_CleanupPublicTemplate(template);
|
||||
}
|
||||
|
||||
/* non-device functions: template and auth */
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetKeyTemplate_RSA")]
|
||||
private static extern int wolfTPM2_GetKeyTemplate_RSA(IntPtr publicTemplate,
|
||||
ulong objectAttributes);
|
||||
public int GetKeyTemplate_RSA(ulong objectAttributes)
|
||||
{
|
||||
return wolfTPM2_GetKeyTemplate_RSA(template,
|
||||
objectAttributes);
|
||||
}
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetKeyTemplate_Symmetric")]
|
||||
private static extern int wolfTPM2_GetKeyTemplate_Symmetric(
|
||||
IntPtr publicTemplate, int keyBits, uint algMode, int isSign,
|
||||
int isDecrypt);
|
||||
|
||||
public int GetKeyTemplate_Symmetric(int keyBits,
|
||||
TPM2_Alg algMode,
|
||||
bool isSign,
|
||||
bool isDecrypt)
|
||||
{
|
||||
return wolfTPM2_GetKeyTemplate_Symmetric(template,
|
||||
keyBits,
|
||||
(uint)algMode,
|
||||
isSign ? 1 : 0,
|
||||
isDecrypt ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class Session
|
||||
{
|
||||
const string DLLNAME = "wolftpm";
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetNewSession")]
|
||||
private static extern IntPtr wolfTPM2_GetNewSession();
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_CleanupSession")]
|
||||
private static extern int wolfTPM2_CleanupSession(IntPtr session);
|
||||
|
||||
|
||||
internal IntPtr session;
|
||||
|
||||
public Session()
|
||||
{
|
||||
session = wolfTPM2_GetNewSession();
|
||||
}
|
||||
|
||||
~Session()
|
||||
{
|
||||
if (session != IntPtr.Zero)
|
||||
{
|
||||
// TODO: check return value
|
||||
wolfTPM2_CleanupSession(session);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Device
|
||||
{
|
||||
/* ================================================================== */
|
||||
/* Constants */
|
||||
/* ================================================================== */
|
||||
|
||||
const string DLLNAME = "wolftpm";
|
||||
|
||||
public const int MAX_KEYBLOB_BYTES = 1024;
|
||||
private IntPtr device = IntPtr.Zero;
|
||||
|
||||
public Device()
|
||||
{
|
||||
device = wolfTPM2_New();
|
||||
}
|
||||
|
||||
~Device()
|
||||
{
|
||||
if (device != IntPtr.Zero)
|
||||
{
|
||||
wolfTPM2_Free(device);
|
||||
}
|
||||
}
|
||||
/* Note that this one is not an empty; it actually calls wolfTPM2_Init()
|
||||
* as a convenience for the user. */
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_New")]
|
||||
private static extern IntPtr wolfTPM2_New();
|
||||
|
||||
/* WOLFTPM_API int wolfTPM2_SimpleCleanup(WOLFTPM2_DEV *dev); */
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_Free")]
|
||||
private static extern int wolfTPM2_Free(IntPtr dev);
|
||||
|
||||
/* ================================================================== */
|
||||
/* Native Wrappers */
|
||||
/* ================================================================== */
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_SelfTest")]
|
||||
private static extern int wolfTPM2_SelfTest(IntPtr dev);
|
||||
public int SelfTest()
|
||||
{
|
||||
return wolfTPM2_SelfTest(device);
|
||||
}
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_GetRandom")]
|
||||
private static extern int wolfTPM2_GetRandom(IntPtr dev,
|
||||
byte[] buf,
|
||||
int len);
|
||||
public int GetRandom(byte[] buf)
|
||||
{
|
||||
return wolfTPM2_GetRandom(device, buf, buf.Length);
|
||||
}
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_CreateSRK")]
|
||||
private static extern int wolfTPM2_CreateSRK(IntPtr dev,
|
||||
IntPtr srkKey,
|
||||
int alg,
|
||||
string auth,
|
||||
int authSz);
|
||||
public int CreateSRK(Key srkKey,
|
||||
int alg,
|
||||
string auth)
|
||||
{
|
||||
return wolfTPM2_CreateSRK(device,
|
||||
srkKey.key,
|
||||
alg,
|
||||
auth,
|
||||
auth.Length);
|
||||
}
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_StartSession")]
|
||||
private static extern int wolfTPM2_StartSession(IntPtr dev, IntPtr session,
|
||||
IntPtr tmpKey, IntPtr bind, byte sesType, int encDecAlg);
|
||||
public int StartSession(IntPtr session,
|
||||
Key tmpKey,
|
||||
IntPtr bind,
|
||||
byte sesType,
|
||||
int encDecAlg)
|
||||
{
|
||||
return wolfTPM2_StartSession(device,
|
||||
session,
|
||||
tmpKey.key,
|
||||
bind,
|
||||
sesType,
|
||||
encDecAlg);
|
||||
}
|
||||
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_ReadPublicKey")]
|
||||
private static extern int wolfTPM2_ReadPublicKey(IntPtr dev,
|
||||
IntPtr key,
|
||||
ulong handle);
|
||||
public int ReadPublicKey(Key key,
|
||||
ulong handle)
|
||||
{
|
||||
return wolfTPM2_ReadPublicKey(device,
|
||||
key.key,
|
||||
handle);
|
||||
}
|
||||
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_CreateKey")]
|
||||
private static extern int wolfTPM2_CreateKey(
|
||||
IntPtr dev,
|
||||
IntPtr keyBlob,
|
||||
IntPtr parent,
|
||||
IntPtr publicTemplate,
|
||||
string auth,
|
||||
int authSz);
|
||||
public int CreateKey(KeyBlob keyBlob,
|
||||
Key parent,
|
||||
Template publicTemplate,
|
||||
string auth)
|
||||
{
|
||||
return wolfTPM2_CreateKey(device,
|
||||
keyBlob.keyblob,
|
||||
parent.GetHandleRefFromKey(),
|
||||
publicTemplate.template,
|
||||
auth,
|
||||
auth.Length);
|
||||
}
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_LoadKey")]
|
||||
private static extern int wolfTPM2_LoadKey(
|
||||
IntPtr dev,
|
||||
IntPtr keyBlob,
|
||||
IntPtr parent);
|
||||
public int LoadKey(KeyBlob keyBlob,
|
||||
Key parent)
|
||||
{
|
||||
return wolfTPM2_LoadKey(device, keyBlob.keyblob, parent.GetHandleRefFromKey());
|
||||
}
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_ImportRsaPrivateKey")]
|
||||
private static extern int wolfTPM2_ImportRsaPrivateKey(
|
||||
IntPtr dev,
|
||||
IntPtr parentKey,
|
||||
IntPtr keyBlob,
|
||||
byte[] rsaPub,
|
||||
int rsaPubSz,
|
||||
int exponent,
|
||||
byte[] rsaPriv,
|
||||
int rsaPrivSz,
|
||||
uint scheme,
|
||||
uint hashAlg);
|
||||
|
||||
public int ImportRsaPrivateKey(
|
||||
Key parentKey,
|
||||
KeyBlob keyBlob,
|
||||
byte[] rsaPub,
|
||||
int exponent,
|
||||
byte[] rsaPriv,
|
||||
uint scheme,
|
||||
uint hashAlg)
|
||||
{
|
||||
return wolfTPM2_ImportRsaPrivateKey(device,
|
||||
parentKey.key,
|
||||
keyBlob.keyblob,
|
||||
rsaPub,
|
||||
rsaPub.Length,
|
||||
exponent,
|
||||
rsaPriv,
|
||||
rsaPriv.Length,
|
||||
scheme,
|
||||
hashAlg);
|
||||
}
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_LoadRsaPublicKey")]
|
||||
private static extern int wolfTPM2_LoadRsaPublicKey(
|
||||
IntPtr dev,
|
||||
IntPtr key,
|
||||
byte[] rsaPub,
|
||||
int rsaPubSz,
|
||||
int exponent);
|
||||
public int LoadRsaPublicKey(Key key,
|
||||
byte[] rsaPub,
|
||||
int exponent)
|
||||
{
|
||||
return wolfTPM2_LoadRsaPublicKey(device,
|
||||
key.key,
|
||||
rsaPub,
|
||||
rsaPub.Length,
|
||||
exponent);
|
||||
}
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_LoadRsaPrivateKey")]
|
||||
private static extern int wolfTPM2_LoadRsaPrivateKey(
|
||||
IntPtr dev,
|
||||
IntPtr parentKey,
|
||||
IntPtr key,
|
||||
byte[] rsaPub,
|
||||
int rsaPubSz,
|
||||
int exponent,
|
||||
byte[] rsaPriv,
|
||||
int rsaPrivSz);
|
||||
public int LoadRsaPrivateKey(
|
||||
Key parentKey,
|
||||
Key key,
|
||||
byte[] rsaPub,
|
||||
int exponent,
|
||||
byte[] rsaPriv)
|
||||
{
|
||||
return wolfTPM2_LoadRsaPrivateKey(
|
||||
device,
|
||||
parentKey.key,
|
||||
key.key,
|
||||
rsaPub,
|
||||
rsaPub.Length,
|
||||
exponent,
|
||||
rsaPriv,
|
||||
rsaPriv.Length);
|
||||
}
|
||||
|
||||
[DllImport(DLLNAME, EntryPoint = "wolfTPM2_UnloadHandle")]
|
||||
private static extern int wolfTPM2_UnloadHandle(IntPtr dev, IntPtr handle);
|
||||
public int UnloadHandle(Key key)
|
||||
{
|
||||
return wolfTPM2_UnloadHandle(device, key.key);
|
||||
}
|
||||
|
||||
public int UnloadHandle(KeyBlob keyblob)
|
||||
{
|
||||
return wolfTPM2_UnloadHandle(device, keyblob.keyblob);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# vim:ft=automake
|
||||
# All paths should be given relative to the root
|
||||
|
||||
include wrapper/CSharp/include.am
|
||||
|
||||
wrapperdir = $(docdir)/wrapper
|
||||
dist_wrapper_DATA= wrapper/wolfTPM-csharp.sln
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31205.134
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wolfTPM-csharp", "CSharp\wolfTPM-csharp.csproj", "{B94757A8-B2A3-4289-887D-A0B23C34F418}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B94757A8-B2A3-4289-887D-A0B23C34F418}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B94757A8-B2A3-4289-887D-A0B23C34F418}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B94757A8-B2A3-4289-887D-A0B23C34F418}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B94757A8-B2A3-4289-887D-A0B23C34F418}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C5F3DA80-4658-45F2-9224-EF22CAD6108B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
Loading…
Reference in New Issue