Added TSS Code Gen README; updated TSS.MSR README; plus minor TssCodeGen code cleanup.

This commit is contained in:
amarochk 2020-09-21 15:18:31 -07:00
Родитель 74fccc9e93
Коммит f0afe4e9e1
7 изменённых файлов: 264 добавлений и 60 удалений

Просмотреть файл

@ -10,42 +10,49 @@ Trusted Platform Module (TPM) is a security component forming roots of trust in
* Secure non-volatile storage
* Other functions including hashing, random number generation, a secure clock, etc.
Microsoft Windows operating system relies on the TPM for a number of its security functions. Examples include BitLocker™ drive encryption, the Windows Virtual Smart Card feature, and the Platform Crypto Provider. Windows 10 [requires](https://docs.microsoft.com/en-us/windows/security/hardware-protection/tpm/tpm-recommendations#tpm-20-compliance-for-windows-10) TPM 2.0 to be enabled in all its desktop editions (Home, Pro, Enterprise, and Education) and in server editions running guarded fabric.
Microsoft Windows operating system relies on the TPM for a number of its security functions. Examples include BitLocker™ drive encryption, the Windows Virtual Smart Card feature, and the Platform Crypto Provider. Windows 10 [requires][Win10Tpm20Compliance] TPM 2.0 to be enabled in all its desktop editions (Home, Pro, Enterprise, and Education) and in server editions running guarded fabric.
Both Windows and Linux operating systems expose low-level programmatic access to their TPM 2.0 devices. On Windows TPM 2.0 is available via TPM Base Services (TBS) API, and on Linux - via /dev/tpm0 or /dev/tpmrm0 device file abstractions. For the purposes of TPM 2.0 application development it is extremely convenient to use the [TPM 2.0 simulator](https://github.com/Microsoft/ms-tpm-20-ref/tree/master/TPMCmd/Simulator) developed, open-sourced, and maintained on behalf of [TCG](http://trustedcomputinggroup.org) by Microsoft.
Both Windows and Linux operating systems expose low-level programmatic access to their TPM 2.0 devices. On Windows TPM 2.0 is available via TPM Base Services (TBS) API, and on Linux - via /dev/tpm0 or /dev/tpmrm0 device file abstractions. For the purposes of TPM 2.0 application development it is extremely convenient to use the [TPM 2.0 simulator] developed, open-sourced, and maintained on behalf of [TCG] by Microsoft.
## TPM Software Stack (TSS) implementations from Microsoft
All flavors of TPM 2.0 devices mentioned in the previous section communicate with applications via a rather complex binary interface defined by the TCG's [TPM 2.0 specification](https://trustedcomputinggroup.org/resource/tpm-library-specification/) wrapped into OS/simulator specific protocols. Writing code for manual creation of the TPM 2.0 command buffers, parsing response buffers, building HMAC and policy sessions, verifying audit data, etc., is extremely tedious, time consuming, and error prone task.
All flavors of TPM 2.0 devices mentioned in the previous section communicate with applications via a rather complex binary interface defined by the TCG's [TPM 2.0 specification] wrapped into OS/simulator specific protocols. Writing code for manual creation of the TPM 2.0 command buffers, parsing response buffers, building HMAC and policy sessions, verifying audit data, etc., is extremely tedious, time consuming, and error prone task.
In order to facilitate the development of applications and services using TPM 2.0, Microsoft has developed a series of TSS implementations for different programming languages. All these implementations provide complete representation of the TPM 2.0 API (commands, data structures, enumerations, unions) using the means of the corresponding languages, and some of them - additional functionality that greatly simplifies communications with TPM 2.0. All TSS.MSR implementations provide abstraction for Windows/Linux/Simulator TPM 2.0 devices.
### TSS.Net and TSS.CPP
### [TSS.Net] and [TSS.CPP]
TSS.Net and TSS.CPP are written in C# and C++ correspondingly, and are the richest TSS implementations in this collection. Besides complete abstraction of the TPM 2.0 interface, they implement additional functionality, such as:
* automatic handling HMAC and policy sessions;
* expected audit, policy and CP-digests computation;
* automatic handling of HMAC and policy sessions;
* expected audit, policy and cpHashes computation;
* object oriented representation of the policy commands;
* multiple helpers simplifying bridging between software crypto and TPM 2.0 based applications.
* multiple helpers simplifying bridging between software crypto and TPM 2.0.
### TSS.Java and TSS.JS
### [TSS.Java], [TSS.JS], and [TSS.Py]
These implementations are for Java language and Node.JS environment, and at the moment they provide complete abstraction of the TPM 2.0 interface without most of the rich capabilities of TSS.Net or TSS.CPP. Node.JS version is written in TypeScript language.
These implementations are for Java, Node.JS, and Python environments, and at the moment they provide complete abstraction of the TPM 2.0 interface without most of the additional capabilities of TSS.Net or TSS.CPP. Node.JS version is written in the TypeScript language.
## Tpm2Tester
## [TSS Code Generator]
This repo also contains a framework for TPM 2.0 test suites creation. See [Tpm2Tester](Tpm2Tester/README.md) for more details.
[TssCodeGen](TssCodeGen/README.md) is the tool that parses [TPM 2.0 specification] documents and updates the TSS implementations in this repo so that all TPM 2.0 entity and command definitions match the contents of the specification. The tool can be easily extended to support other programming languages, as all language specific processing is highly localized and most of the logic is language independent.
## [Tpm2Tester]
This is the TSS.Net based [framework][TestSubstrate] used by the official TPM 2.0 compliance test suite and TPM 2.0 components of the Microsoft [Windows HLK]. See its [README](Tpm2Tester/README.md) document for the details of the framework API and usage.
Along with it comes a [sample test suite][TestSuite] that not only demonstrates the framework usage, but also contains additional samples of the TPM 2.0 use cases, and is convenient for quick prototyping and testing of TPM 2.0 based scenarios.
## System Requirements
TSS.Net is a cross-platform .NET Standard library and requires Visual Studio 2015 Update 3 or above. It can be built to target one of the following .NET framework flavors: .NET 4.6, .NET Core 2.0 (for both Windows and Linux), .NET Standard, .NET UWP 10.0. You can download the latest versions of the .NET Framework [here](https://www.microsoft.com/net/download/windows).
TSS.Net is a cross-platform .NET Standard library and requires Visual Studio 2017 or above to build it. It can target one of the following .NET framework flavors: .NET 4.7.2, .NET Core 2.1 (for both Windows and Linux), .NET Standard 2.0, and .NET UWP 10.0. You can download the latest versions of the .NET Framework [here](https://www.microsoft.com/net/download/windows).
TSS.Java targets Java SE 8 or above, and TSS.JS.
TSS.Java uses Java SE 8 or above, TSS.JS requires Node.js 4.8.4 or higher, and TSS.Py supports Python 2.7 and 3.5+.
## Platform Crypto Provider Toolkit
The TSS.MSR project also provides the TPM Platform Crypto Provider Toolkit. It contains sample code, utilities, and documentation for using TPM-related functionality on Windows 8.x systems. It covers TPM-backed Crypto-Next-Gen (CNG) Platform Crypto Provider, and how attestation service providers can use the new Windows 8.x features. Both TPM 1.2 and TPM 2.0-based systems are supported.
The TSS.MSR project also provides the TPM Platform Crypto Provider Toolkit. It contains sample code, utilities, and documentation for using TPM-related functionality on Windows 8.x/10 systems. It covers TPM-backed Crypto-Next-Gen (CNG) Platform Crypto Provider, and illustrates how attestation service providers can use the new Windows 8.x features. Both TPM 1.2 and TPM 2.0-based systems are supported.
## See Also
@ -56,4 +63,22 @@ The TSS.MSR project also provides the TPM Platform Crypto Provider Toolkit. It
We hope that the TSS.MSR project will prove useful to both software developers and researchers in their development of security solutions and applications for the Windows operating system.
Please send questions and feedback to tssdotnet@microsoft.com or tssdotcpp@microsoft.com.
Feel free to use Issues section of this Github repo for any quetsions or problems.
For private feedback please use tssdotnet@microsoft.com (for all managed languages) or tssdotcpp@microsoft.com mailing lists.
[TSS.Net]: ./TSS.NET
[TSS.CPP]: ./TSS.CPP
[TSS.Java]: ./TSS.Java
[TSS.JS]: ./TSS.JS
[TSS.Py]: ./TSS.Py
[TSS Code Generator]: ./TssCodeGen
[Tpm2Tester]: ./Tpm2Tester
[TestSubstrate]: ./Tpm2Tester/TestSubstrate
[TestSuite]: ./Tpm2Tester/TestSuite
[TCG]: http://trustedcomputinggroup.org
[TPM 2.0 simulator]: https://github.com/Microsoft/ms-tpm-20-ref/tree/master/TPMCmd/Simulator
[TPM 2.0 specification]: https://trustedcomputinggroup.org/resource/tpm-library-specification/
[Windows HLK]: https://docs.microsoft.com/en-us/windows-hardware/test/hlk/
[Win10Tpm20Compliance]: https://docs.microsoft.com/en-us/windows/security/hardware-protection/tpm/tpm-recommendations#tpm-20-compliance-for-windows-10

Просмотреть файл

@ -393,7 +393,4 @@ This folder contains three projects:
TestSubstrate and TestSuite projects depend on the [TSS.Net](https://github.com/Microsoft/TSS.MSR/tree/master/TSS.NET) project from this repo.
## System Requirements
Tpm2Tester is a cross-platform .Net Standard library and requires Visual Studio 2015 Update 3 to build.
## Questions and Feedback
Please send questions and feedback to tssdotnet@microsoft.com.
Tpm2Tester is a cross-platform .NET Standard library and requires Visual Studio 2017 or above to build it. It can target one of the following .NET framework flavors: .NET 4.7.2, .NET Standard 2.0.

180
TssCodeGen/README.md Normal file
Просмотреть файл

@ -0,0 +1,180 @@
# **TSS Code Generator (*TssCodeGen*)**
# Purpose
This is the tool that automatically (re)generates the interface part of the TPM Software Stack (TSS) implementations for all supported programming languages/frameworks ([.Net][TSS.Net], [C++][TSS.CPP], [Java][TSS.Java], [Node.js][TSS.JS], [Python][TSS.Py]) based on the TCG's [TPM 2.0 specification] documents.
Auto-generated code includes the following components of the TPM 2.0 interface:
* constants (represented as enums);
* flags (represented as enums);
* bitfields (represented as enums);
* data structures (represented as classes) with their marshaling code (or metadata in the case of .Net);
* unions (represented as interfaces or abstract classes) and their factory (used when unmarshaling);
* command prototypes (represented as methods of the main `Tpm2` class) and classes encapsulating sets of input parameters (used only internally by the TSS implementations) and output values (when a command has multiple response parameters).
# Usage
When built and run in-place from a Visual Studio with no command line options provided, the tool will pick the TPM 2.0 specification data from the [TpmSpec](./TpmSpec) directory, and update TSS for all supported languages in this repo clone.
If the tool is used from a directory different from the one used by the Visual Studio build, you may need to use command line options to specify the location of the TPM 2.0 specification documents (`-spec`) and the target TSS implementations (`-dest`). You can also specify a subset of target TSS programming languages to update using a combination of options `-dotNet`, `-cpp`, `-java`, `-node`, `-py`.
Run the tool with the `-help` option to get more detailed information about its command line options.
# Architecture
This section gives a high level overview of the *TssCodeGen* architecture.
Originally created as a .Net-only tool *TssCodeGen* gradually evolved to support TSS written in other programming languages (first C++ was added, then Java, then Node.js and Python). The primary purpose of its current design is maximal unification across different programming languages both on the side of the tool and on the side of the resulting TSS, so that adding new languages or adopting changes in the TPM 2.0 specification requires only minimal modifications in the tool code base.
## *High level workflow*
The tool works in three phases:
1) Table extraction phase.
If the the specifications folder (`-spec` command line option) contains an XML file `RawTables.xml` and no `-extract` command line option was used, then this step is bypassed.
Otherwise, the [TableExtractor](./src/TableExtractor.cs) class:
* Parses the TPM 2.0 spec documents (*Part 2* and *Part 3* of the TPM 2.0 Specification, *TCG Algorithm Registry*, and *TPM 2.0 Vendor-Specific*).
* Extracts tables with the definitions of all the required TPM 2.0 entities (data structures, unions, constants, attributes, commands, algorithm descriptions) together with the corresponding descriptions or surrounding text fragments to be used as comments.
* Saves extracted data in the XML file `RawTables.xml` located in the same specifications directory.
Note that table extraction logic uses Microsoft Office interop API that is very slow, this is why it is recommended to keep the intermediate `RawTables.xml` file with extracted data until the specification documents change.
2) Type extraction phase.
The tool reads the `RawTables.xml` file, and uses the [TypeExtractor](./src/TypeExtractor.cs) class to parse the TPM 2.0 specification tables and create an internal abstract syntax tree (AST) representing all TPM 2.0 entities.
During the extraction process, the tool:
* Transcribes data types defined in the TPM 2.0 specification expanding *agile algorithm notation* (`!ALG.<`*`AlgSpec`*`>`) based on the *TCG Algorithm Registry* document contents.
* Creates artificial data structures representing TPM 2.0 commands.
* Creates `NULL-data structures` (corresponding to the universal `ALG_ID_NULL` selector).
At the postprocessing step the type extractor performs the following transformations:
* Adds fundamental integer and Boolean data type definitions;
* Adds a few custom data structures making TSS interface more convenient;
* For data structures with members of the types belonging to the following TPM 2.0 type families:
- sized arrays and data structures (`TPM2B_`)
- lists (`TPML_`)
- typedefs (`TPMI_`)
flattens them by replacing original types directly with their innermost array/struct/value types.
3) Code generation phase.
A specialized class for each of the target program language ([CGenDotNet](./src/CGenDotNet.cs), [CGenCpp](./src/CGenCpp.cs), [CGenJava](./src/CGenJava.cs), [CGenNode](./src/CGenNode.cs), [CGenPy](./src/CGenPy.cs)) produces the code based on the AST representation.
## *Abstract Syntax Tree (AST) classes*
Classes representing AST elements are defined in the [TpmTypes.cs](./src/TpmTypes.cs) source file. There are three main groups of them:
* Data types: `TpmValueType`, `TpmEnum`, `TpmBitfield`, `TpmStruct`, `TpmUnion`, `TpmTypedef`. They are all derived from the `TpmType` base class.
* Fields of different kinds: `BitfieldElement`, `StructField`, `UnionMember`. They are all derived from the `TpmField` base class.
* Two classes representing constants and flags: `TpmConstExpr` and `TpmNamedConstant`. Constants defined in the TPM 2.0 specification as expressions (usually involving other constants) are evaluated using helper classes from the [Expression.cs](./src/Expression.cs) source file.
Note that there is no special AST class type for TPM commands. This is because a command is represented by a pair of `TpmStruct` classes comprising sets of its input and response parameters.
Some instances of the `StructField` classes reference metadata of the `Domain` type (defined together with other pertaining types in the [Domain.cs](./src/Domain.cs) source file). They define possible ranges or sets of values for for the corersponding data structure fields. Only [TSS.Net] has this information transferred to its code - it was used for validation purposes during early stages of the TPM 2.0 development, and is currently used by the [TPM 2.0 testing framework](../Tpm2Tester/TestSubstrate) for deep-penetration fuzzing purposes. Code generators for other languages ignore these metadata.
## *Mapping TPM 2.0 specification syntax and naming conventions to the target languages*
Even though [TPM 2.0 specification] defines TPM 2.0 entities and commands by means of programming lnguage neutral MS Word tables, the overall design of the TPM 2.0 API surface implies a C implementation (after all, C is the language of the [TPM 2.0 reference implementation]). The naming conventions used by the specification are ALL_CAPS for most of the TPM 2.0 type and constant names, mixed ALL_CAPS/CamelStyle for commands, and camelStyle for attribute amd field names. It also uses a set of eight different `TPMX_` prefixes to mark different kinds of data types, and multiple prefixes to form logical groups of constants. Such, somewhat eclectic (partly because of the TPM 1.2 legacy), naming conventions are quite different from those used by the majority of modern programming language communities. This was why for the [TSS.Net] (that was the first TSS ever built for TPM 2.0) it was decided to apply blanket name translation to the CamelCase style commonly used by .Net developers. However, for language bindings added later the name translation is almost completely avoided to simplify both the TPM 2.0 specification usage by developers and porting abundant TPM 2.0 code written in C to the new TSS languages.
To simplify adding new programming languages and make the tool code more lucid the majority of target language specific transformations are encapsulated in the [TargetLang] and [TpmTypeTranslations](./src/TpmTranslations.cs) classes. Class [TargetLang], in particular, abstracts the syntax and representation of fundamental types, member references, conditions, etc.
Except for TSS.Net, names used by the TPM 2.0 specification are mostly left intact, except that the `TPM2_` prefix is dropped from the command names when they are made methods of the `Tpm2` class, and prefixes of constants and attributes are separated and serve as the containing *enum* names. C++ variant uses different capitalization for some method names.
Naming conventions used by [TSS.Net] are different due to legacy reasons (a large body of existing code ). It converts ALL_CAPS style of the TPM 2.0 specification to the CamelCase traditional for .Net, and aggressively eliminates various `TPMX_` prefixes by either dropping them completely or converting them into enum names or type name suffixes. TSS.Net also relies heavily on the reflection capabilities absent in most other languages, so instead of producing marshaling and serialization code the .Net code generator only adds metadata to the classes and data fields. (Reflection is also used as the foundation for the advanced TPM 2.0 testing infrastructure built on top of TSS.Net.)
Type extractor generates `TpmEnum` AST classes for the constants defined in the TPM 2.0 specification (often as values of a `TPMI_` typedef type). TPM 2.0 attributes are represented by the `TpmBitfield` AST classes with a collection of related `BitfieldElement` instances. Both `TpmEnum` and `TpmBitfield` are mapped to *enums* in the target languages. In C++ and Java versions enums are implemented using classes to preserve common usage model across different languages (the design of the enums support in Java is particularly weird because of complete absence of user defined type conversions in the language).
TPM 2.0 specification profusely uses C typedefs to specify different restrictions on different usages of values of the same underlying type. Since such bounds checks are meaningless on the TSS side, `TpmTypedef` AST classes are always represented with their underlying types: fundamental integral/Boolean, enum or class.
TPM 2.0 specification also intensively uses tagged unions. Since none of the managed languages support unions in any meaningful way (e.g. .Net CLR allows defining unions of references, but not of data structures), a TPM 2.0 union represented by an instance of the `TpmUnion` AST class is mapped to an *interface* (or an abstract base class) with a single `GetUnionSelector()` method. Union members represented by a collection of the `UnionMember` AST classes become data structures that implement the corresponding union interface, with the `GetUnionSelector()` method returning the tag value (usually an algorithm ID) that specifies which union member is currently "active". E.g., the following C union:
```C
union TPMU_SCHEME_KEYEDHASH {
TPMS_SCHEME_HMAC hmac;
TPMS_SCHEME_XOR xor;
TPMS_NULL_SCHEME_KEYEDHASH null;
};
```
is represented in the following manner:
```JS
interface TPMU_SCHEME_KEYEDHASH
{
GetUnionSelector(): TPM_ALG_ID;
}
class TPMS_SCHEME_HMAC extends TpmStructure implements TPMU_SCHEME_KEYEDHASH { ... }
class TPMS_SCHEME_XOR extends TpmStructure implements TPMU_SCHEME_KEYEDHASH { ... }
class TPMS_NULL_SCHEME_KEYEDHASH extends TpmStructure implements TPMU_SCHEME_KEYEDHASH, TPMU_SIG_SCHEME, ... { ... }
```
Note that even though C++ can easily represent unions using original C notation, `TSS.CPP` nevertheless uses the same interface based approach for the sake of uniformity across all the supported languages.
## *Code generation phase*
Auto-generated code for all TSS language bindings uses mostly the same unified architecture and naming conventions (with .Net being more different than the others). Correspondingly, code generation workflows for different languages are very similar, too.
Code generator classes for all languages inherit from the same base class [CodeGenBase](./src/CodeGenBase.cs) that implements the following common functionality:
* Output formatting infrastructure: a family of `Write()`, `TabIn()`, and `TabOut()` methods;
* Commentary formatting using the current target language specific annotation conventions: a family of `WriteComment()` methods, `GetParamComment()`, and `GetReturnComment()`;
* Snippets handling: `LoadSnips()` and `InsertSnip()`;
* TPM bitfields processing: `GetBifieldElements()`;
* Marshaling code generation: `GetToTpmFieldsMarshalOps()` and `GetFromTpmFieldsMarshalOps()`.
.Net variant requires sweeping name conversion, while other languages also apply some limited name transformations. On the other hand, expressions that specify values of many constants also need translation to the target language syntax. To avoid repeated conversions during code generation and to unify the code of the code generators across different target languages, AST classes use a pair of members to represent each type name, struct/union member name, or arithmetic expression (e.g. `SpecName` and `Name`, or `SpecValue` and `Value`). The first member of each pair keeps the original name used by the TPM 2.0 specifiaction. It is set during the type extraction phase and never changes. The second member of the pair is updated by `TargetLang.SetTargetLang()` as described below.
To generate code for the given target language the tool:
* Invokes the `TargetLang.SetTargetLang()` method that:
- Properly updates global language dependent settings.
- Walks the whole AST and updates the target language dependent members (type/field names and expressions) with the results of the original name or expression translation to the target language syntax/conventions.
* Instantiates the corresponding code generator class.
* invokes its overridden `CodeGenBase.Generate()` method that produces the actual code.
The `CodeGenBase.Generate()` method implements the same generic workflow for all target languages. It walks the AST class several times (except for Java that only needs two passes, as it stores each definition in a separate source file) in order to generate the TPM entities in the following order:
* Enum definitions from the `TpmEnum` instances.
* Enum definitions from the `TpmBitfield` and realted `BitfieldElement` instances.
* TPM union interfaces definitions from the `TpmUnion` instances.
* TPM union factory implementation from the collection of the `UnionMember` and realted `UnionMember` instances.
- Union factory is used to instantiate the correct union member (class implementing the given union interface) based on the union type and selector (tag) value. This is necessary while unmarshaling TPM structures with fields of a union type.
* Class definitions from all `TpmStruct` instances. This includes field definitions, constructors, marshaling methods (except for [TSS.Net]), and on case-by-case basis additional interface methods.
- The set of automatically generated methods for a few TPM 2.0 structures is extended with custom additions via .snips files ([C++](../TSS.CPP/Src/TpmExtensions.cpp.snips), [Java](../TSS.Java/src/TpmExtensions.java.snips), [Node.js](../TSS.JS/src/TpmExtensions.js.snips), [Python](../TSS.Py/src/TpmExtensions.py.snips)). Snippet files contain fragments of the code that are appended to the auto-generated classes (class declarations in the case of C++) without any additional translations. Note that [TSS.Net] does not use this mechanism, as it custmizes its auto-generated classes using *partial classes* syntax.
* TPM command definitions from the select `TpmStruct` instances representing command and response parameters.
.Net code generator additionally creates a static class with marshaling metadata `CommandInformation`, and for C++ two maps for enum-to-string and string-to-enum conversions (`Enum2StrMap` and `Str2EnumMap`) are generated.
Generated code is accumulated in an internal buffer and then is written out to a destination source file. The mapping of the produced definitions to the source files is different for different target languages (mostly for historical reasons, and in the case of Java it is the language requirement):
* [TSS.JS] and [TSS.Py] use identical source files organization. They keep all TPM data types and the union factory definitions in one source ([TpmTypes.ts](../TSS.JS/src/TpmTypes.ts) and [TpmTypes.py](../TSS.Py/src/TpmTypes.py)), and TPM commands in the other ([Tpm.ts](../TSS.JS/src/Tpm.ts) and [Tpm.py](../TSS.Py/src/Tpm.py)).
* [TSS.CPP] follows [TSS.JS]/[TSS.Py] in splitting the TPM data type and command *declarations* between two header files ([TpmTypes.h](../TSS.CPP/include/TpmTypes.h) and [Tpm2.h](../TSS.CPP/include/Tpm2.h)). Yet it additionally creates the third source file for the *definitions* of marshaling methods, union factory and enum names conversion maps ([TpmTypes.cpp](../TSS.CPP/Src/TpmTypes.cpp)).
- Note also that in contrast to other languages the C++ output sources are not completely (re)created by the code generator, but are rather *updated* by means of replacing their sections marked by the `<<AUTOGEN_BEGIN>>` comment with the new auto-generated code.
* [TSS.Net] places all auto-generated definitions in the single source file ([X_TpmDefs.cs](../TSS.NET/TSS.NET/X_TpmDefs.cs)).
* Java keeps each definition in its own [separate source file](../TSS.Java/src/tss/tpm), plus [Tpm.java](../TSS.Java/src/tss/Tpm.java) for TPM command definitions.
[TSS.Net]: ../TSS.NET
[TSS.CPP]: ../TSS.CPP
[TSS.Java]: ../TSS.Java
[TSS.JS]: ../TSS.JS
[TSS.Py]: ../TSS.Py
[TargetLang]: ./src/TargetLang.cs
[TPM 2.0 specification]: https://trustedcomputinggroup.org/resource/tpm-library-specification/
[TPM 2.0 reference implementation]: https://github.com/Microsoft/ms-tpm-20-ref

Просмотреть файл

@ -134,7 +134,6 @@ namespace CodeGen
void GenBitfield(TpmBitfield bf)
{
GenEnum(bf, GetBifieldElements(bf));
}
void GenUnion(TpmUnion u)

Просмотреть файл

@ -16,10 +16,10 @@ using System.Xml.Serialization;
* Entry point for the code generatator.
*
* This program works in three phases:
* 1) Parses Part 2 and 3 of the TPM 2.0 spec, extracts the definitions of TPM 2.0 data structures,
* constants, and commands and saves them as in an XML file. If the XML file with the definitions
* already exists, then this step is skipped by default. It can be enforced with the '-extract'
* command line option.
* 1) Parses Part 2 and 3 of the TPM 2.0 spec, extracts tables with the definitions of TPM 2.0 data
* structures, constants, unions, and commands and saves them as in an XML file (RawTables.xml).
* If RawTables.xml already exists, then this step is skipped by default. It can be enforced
* with the '-extract' command line option.
* 2) Reads the XML file with extracted definitions and creates internal abstract syntax tree (AST)
* of the TPM 2.0 entities.
* 3) Generates the code for the target program languages (all supported languages by default, or as
@ -78,10 +78,10 @@ namespace CodeGen
static void Main(string[] args)
{
bool help = false, abort = false;
bool help = false;
string specPath = null;
string tssRootPath = null;
var actions = Action.None;
Action actions = Action.None;
Func<Lang, string> langName = l => Enum.GetName(typeof(Lang), l);
@ -94,7 +94,7 @@ namespace CodeGen
if (opt[0] != '-' && opt[0] != '/')
{
help = abort = true;
help = true;
PrintError($"Invalid format for option {i}: {opt}");
break;
}
@ -142,7 +142,7 @@ namespace CodeGen
}
else
{
help = abort = true;
help = true;
PrintError($"Unrecognized option '{opt}'");
}
}
@ -151,17 +151,38 @@ namespace CodeGen
if (help)
{
Console.WriteLine("\nAll command line parameters are case-insensitive and optional.\n" +
Console.WriteLine("TSS Code Generator tool.\n" +
"Copyright (c) Microsoft Corporation. All rights reserved.\n" +
"\n" +
"This tool (re)generates the interface part of the TPM Software Stack (TSS)\n" +
"implementations for all supported programming languages/frameworks (TSS.Net,\n" +
"TSS.CPP, TSS.Java, TSS.JS, TSS.Py)\n" +
"\n" +
"All command line parameters are case-insensitive and optional.\n" +
"Option names are prepended with either dash ('-') or slash ('/') marks.\n" +
" They include:\n" +
" spec <path> - a path to the root folder that contains the TPM 2.0 spec Word\n" +
" documents and/or intermediate XML representation\n" +
" dest <path> - a path to the root folder that contains the TPM 2.0 spec Word\n" +
" documents and/or intermediate XML representation\n" +
" noExtract, dotNet, cpp, java, noDotnet, noCpp, noJava, h|help|?" +
"Options are case-insensitive, and must be prepended by characters '-' or '/'\n");
if (abort)
return;
"\n" +
"The following options are supported:\n" +
" h|help|? - Display this message\n" +
" spec <path> - Path to the folder containing the TPM 2.0 specification Word\n" +
" documents and/or intermediate XML representation (RawTables.xml).\n" +
" By default the TssCodeGen/TpmSpec folder is used.\n" +
" dest <path> - Path to the root folder containing individual TSSes to be updated.\n" +
" By default the TSS implementations in this repo clone (in the\n" +
" folders adjasent to the TssCodeGen folder) are updated.\n" +
" extract - Force parsing the TPM 2.0 spec documents even if the intermediate\n" +
" XML representation file (RawTables.xml) is available. By default\n" +
" the tool will always use RawTables.xml if it is present.\n" +
" dotNet, cpp, java, node, py - Any combination of these options can be used\n" +
" to select TSS implementations to be updated. By default (when\n" +
" none of them is present) all supported languages are updated.\n" +
"\n" +
"Note that the default path values used by the tool are selected in expectation\n" +
"that it is run from the Visual Studio after being built from its github repo clone.\n" +
"If however the binary location or folder structure is different, options 'spec'\n" +
"and 'dest' will be required." +
"\n"
);
return;
}
// The TPM 2.0 spec Word docs Part 2 and 3 are parsed to produce an XML representation.
@ -202,8 +223,6 @@ namespace CodeGen
TypeExtractor tpe = new TypeExtractor(tables);
tpe.Extract();
TpmTypeTranslations.DoFixups();
if (tssRootPath == null)
tssRootPath = @"..\..\..\..\";
@ -227,7 +246,7 @@ namespace CodeGen
TargetLang.SetTargetLang(Lang.DotNet);
dotNetGen.Generate();
}
Console.WriteLine("All done!");
Console.WriteLine("\nAll done!");
}
public static void XmlSerializeToFile(String FileName, Object o)

Просмотреть файл

@ -11,6 +11,8 @@ using System.Text.RegularExpressions;
namespace CodeGen
{
/// <summary> Static class containing dictionaries with AST classes and their access and manipulation helpers </summary>
public static class TpmTypes
{
static public readonly string EmptyUnionBaseName = "TPMS_NULL_UNION";
@ -75,14 +77,6 @@ namespace CodeGen
return;
}
internal static void Replace(TpmType tpmType, string insertAfter)
{
Debug.Assert(TypeIndex.ContainsKey(tpmType.SpecName));
TheTypes.Remove(TypeIndex[tpmType.SpecName]);
TypeIndex.Remove(tpmType.SpecName);
Add(tpmType, insertAfter);
}
internal static bool Remove(string typeName)
{
if (!TypeIndex.ContainsKey(typeName))
@ -123,17 +117,6 @@ namespace CodeGen
return true;
}
internal static bool RenameConstant(string curName, string newName)
{
var nc = LookupConstant(curName);
if (nc == null)
return false;
ConstantIndex.Remove(curName);
nc.SpecName = newName;
ConstantIndex.Add(curName, nc);
return true;
}
internal static TpmNamedConstant LookupConstant(string constantName)
{
if (!ConstantIndex.ContainsKey(constantName))

Просмотреть файл

@ -428,6 +428,7 @@ namespace CodeGen
// Add definitions of additional structures not defined in the TPM 2.0 spec.
AddTssStructs();
TpmTypeTranslations.DoFixups();
}
// Add utility structures exposed and used by the TSS framework.