tpm2: rev155: Add ASN.1 related code

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2019-06-12 18:58:25 -04:00 committed by Stefan Berger
parent e5a67ccde9
commit 83221ed68e
4 changed files with 791 additions and 0 deletions

View File

@ -257,6 +257,7 @@ libtpms_tpm2_la_SOURCES = \
tpm2/TestingCommands.c \
tpm2/Ticket.c \
tpm2/Time.c \
tpm2/TpmAsn1.c \
tpm2/TpmSizeChecks.c \
tpm2/TPMCmdp.c \
tpm2/TpmFail.c \
@ -467,6 +468,8 @@ noinst_HEADERS += \
tpm2/Time_fp.h \
tpm2/TPMB.h \
tpm2/TpmAlgorithmDefines.h \
tpm2/TpmAsn1.h \
tpm2/TpmAsn1_fp.h \
tpm2/TpmBuildSwitches.h \
tpm2/TpmError.h \
tpm2/TpmFail_fp.h \

499
src/tpm2/TpmAsn1.c Normal file
View File

@ -0,0 +1,499 @@
/********************************************************************************/
/* */
/* TPM ASN.1 */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id$ */
/* */
/* Licenses and Notices */
/* */
/* 1. Copyright Licenses: */
/* */
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
/* this specification (the "Source Code") a worldwide, irrevocable, */
/* nonexclusive, royalty free, copyright license to reproduce, create */
/* derivative works, distribute, display and perform the Source Code and */
/* derivative works thereof, and to grant others the rights granted herein. */
/* */
/* - The TCG grants to the user of the other parts of the specification */
/* (other than the Source Code) the rights to reproduce, distribute, */
/* display, and perform the specification solely for the purpose of */
/* developing products based on such documents. */
/* */
/* 2. Source Code Distribution Conditions: */
/* */
/* - Redistributions of Source Code must retain the above copyright licenses, */
/* this list of conditions and the following disclaimers. */
/* */
/* - Redistributions in binary form must reproduce the above copyright */
/* licenses, this list of conditions and the following disclaimers in the */
/* documentation and/or other materials provided with the distribution. */
/* */
/* 3. Disclaimers: */
/* */
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
/* information on specification licensing rights available through TCG */
/* membership agreements. */
/* */
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
/* */
/* - Without limitation, TCG and its members and licensors disclaim all */
/* liability, including liability for infringement of any proprietary */
/* rights, relating to use of information in this specification and to the */
/* implementation of this specification, and TCG disclaims all liability for */
/* cost of procurement of substitute goods or services, lost profits, loss */
/* of use, loss of data or any incidental, consequential, direct, indirect, */
/* or special damages, whether under contract, tort, warranty or otherwise, */
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2019 */
/* */
/********************************************************************************/
/* 10.2.23 TpmAsn1.c */
/* 10.2.23.1 Includes */
#include "Tpm.h"
#define _OIDS_
#include "OIDS.h"
#include "TpmAsn1.h"
#include "TpmAsn1_fp.h"
/* 10.2.23.2 Unmarshaling Functions */
/* 10.2.23.2.1 ASN1UnmarshalContextInitialize() */
/* Function does standard initialization of a context. */
/* Return Value Meaning */
/* TRUE(1) success */
/* FALSE(0) failure */
BOOL
ASN1UnmarshalContextInitialize(
ASN1UnmarshalContext *ctx,
INT16 size,
BYTE *buffer
)
{
VERIFY(buffer != NULL);
VERIFY(size > 0);
ctx->buffer = buffer;
ctx->size = size;
ctx->offset = 0;
ctx->tag = 0xFF;
return TRUE;
Error:
return FALSE;
}
/* 10.2.23.2.2 ASN1DecodeLength() */
/* This function extracts the length of an element from buffer starting at offset. */
/* Return Value Meaning */
/* >=0 the extracted length */
/* <0 an error */
INT16
ASN1DecodeLength(
ASN1UnmarshalContext *ctx
)
{
BYTE first; // Next octet in buffer
INT16 value;
//
VERIFY(ctx->offset < ctx->size);
first = NEXT_OCTET(ctx);
// If the number of octets of the entity is larger than 127, then the first octet
// is the number of octets in the length specifier.
if(first >= 0x80)
{
// Make sure that this length field is contained with the structure being
// parsed
CHECK_SIZE(ctx, (first & 0x7F));
if(first == 0x82)
{
// Two octets of size
// get the next value
value = (INT16)NEXT_OCTET(ctx);
// Make sure that the result will fit in an INT16
VERIFY(value < 0x0080);
// Shift up and add next octet
value = (value << 8) + NEXT_OCTET(ctx);
}
else if(first == 0x81)
value = NEXT_OCTET(ctx);
// Sizes larger than will fit in a INT16 are an error
else
goto Error;
}
else
value = first;
// Make sure that the size defined something within the current context
CHECK_SIZE(ctx, value);
return value;
Error:
ctx->size = -1; // Makes everything fail from now on.
return -1;
}
/* 10.2.23.2.3 ASN1NextTag() */
/* This function extracts the next type from buffer starting at offset. It advances offset as it
parses the type and the length of the type. It returns the length of the type. On return, the
length octets starting at offset are the octets of the type. */
/* Return Value Meaning */
/* >=0 the number of octets in type */
/* <0 an error */
INT16
ASN1NextTag(
ASN1UnmarshalContext *ctx
)
{
// A tag to get?
VERIFY(ctx->offset < ctx->size);
// Get it
ctx->tag = NEXT_OCTET(ctx);
// Make sure that it is not an extended tag
VERIFY((ctx->tag & 0x1F) != 0x1F);
// Get the length field and return that
return ASN1DecodeLength(ctx);
Error:
// Attempt to read beyond the end of the context or an illegal tag
ctx->size = -1; // Persistent failure
ctx->tag = 0xFF;
return -1;
}
/* 10.2.23.2.4 ASN1GetBitStringValue() */
/* Try to parse a bit string of up to 32 bits from a value that is expected to be a bit string. If
there is a general parsing error, the context->size is set to -1. */
/* Return Value Meaning */
/* TRUE(1) success */
/* FALSE(0) failure */
BOOL
ASN1GetBitStringValue(
ASN1UnmarshalContext *ctx,
UINT32 *val
)
{
int shift;
INT16 length;
UINT32 value = 0;
//
VERIFY((length = ASN1NextTag(ctx)) >= 1);
VERIFY(ctx->tag == ASN1_BITSTRING);
// Get the shift value for the bit field (how many bits to loop off of the end)
shift = NEXT_OCTET(ctx);
length--;
// the shift count has to make sense
VERIFY((shift < 8) && ((length > 0) || (shift == 0)));
// if there are any bytes left
for(; length > 0; length--)
{
if(length > 1)
{
// for all but the last octet, just shift and add the new octet
VERIFY((value & 0xFF000000) == 0); // can't loose significant bits
value = (value << 8) + NEXT_OCTET(ctx);
}
else
{
// for the last octet, just shift the accumulated value enough to
// accept the significant bits in the last octet and shift the last
// octet down
VERIFY(((value & (0xFF000000 << (8 - shift)))) == 0);
value = (value << (8 - shift)) + (NEXT_OCTET(ctx) >> shift);
}
}
*val = value;
return TRUE;
Error:
ctx->size = -1;
return FALSE;
}
/* 10.2.23.3 Marshaling Functions */
/* 10.2.23.3.1 Introduction */
/* Marshaling of an ASN.1 structure is accomplished from the bottom up. That is, the things that
will be at the end of the structure are added last. To manage the collecting of the relative
sizes, start a context for the outermost container, if there is one, and then placing items in
from the bottom up. If the bottom-most item is also within a structure, create a nested context
by calling ASN1StartMarshalingContext(). */
/* The context control structure contains a buffer pointer, an offset, an end and a stack. offset is
the offset from the start of the buffer of the last added byte. When offset reaches 0, the buffer
is full. offset is a signed value so that, when it becomes negative, there is an overflow. Only
two functions are allowed to move bytes into the buffer: ASN1PushByte() and
ASN1PushBytes(). These functions make sure that no data is written beyond the end of the
buffer. */
/* When a new context is started, the current value of end is pushed on the stack and end is set to
'offset. As bytes are added, offset gets smaller. At any time, the count of bytes in the current
context is simply end - offset. */
/* Since starting a new context involves setting end = offset, the number of bytes in the context
starts at 0. The nominal way of ending a context is to use end - offset to set the length value,
and then a tag is added to the buffer. Then the previous end value is popped meaning that the
context just ended becomes a member of the now current context. */
/* The nominal strategy for building a completed ASN.1 structure is to push everything into the
buffer and then move everything to the start of the buffer. The move is simple as the size of the
move is the initial end value minus the final offset value. The destination is buffer and the
source is buffer + offset. As Skippy would say "Easy peasy, Joe." */
/* It is not necessary to provide a buffer into which the data is placed. If no buffer is provided,
then the marshaling process will return values needed for marshaling. On strategy for filling the
buffer would be to execute the process for building the structure without using a buffer. This
would return the overall size of the structure. Then that amount of data could be allocated for
the buffer and the fill process executed again with the data going into the buffer. At the end,
the data would be in its final resting place. */
/* 10.2.23.3.2 ASN1InitialializeMarshalContext() */
/* This creates a structure for handling marshaling of an ASN.1 formatted data structure. */
void
ASN1InitialializeMarshalContext(
ASN1MarshalContext *ctx,
INT16 length,
BYTE *buffer
)
{
ctx->buffer = buffer;
if(buffer)
ctx->offset = length;
else
ctx->offset = INT16_MAX;
ctx->end = ctx->offset;
ctx->depth = -1;
}
/* 10.2.23.3.3 ASN1StartMarshalContext() */
/* This starts a new constructed element. It is constructed on top of the value that was previously placed in the structure. */
void
ASN1StartMarshalContext(
ASN1MarshalContext *ctx
)
{
pAssert((ctx->depth + 1) < MAX_DEPTH);
ctx->depth++;
ctx->ends[ctx->depth] = ctx->end;
ctx->end = ctx->offset;
}
/* 10.2.23.3.4 ASN1EndMarshalContext() */
/* This function restores the end pointer for an encapsulating structure. */
/* Return Value Meaning */
/* > 0 the size of the encapsulated structure that was just ended */
/* <= 0 an error */
INT16
ASN1EndMarshalContext(
ASN1MarshalContext *ctx
)
{
INT16 length;
pAssert(ctx->depth >= 0);
length = ctx->end - ctx->offset;
ctx->end = ctx->ends[ctx->depth--];
if((ctx->depth == -1) && (ctx->buffer))
{
MemoryCopy(ctx->buffer, ctx->buffer + ctx->offset, ctx->end - ctx->offset);
}
return length;
}
/* 10.2.23.3.5 ASN1EndEncapsulation() */
/* This function puts a tag and length in the buffer. In this function, an embedded BIT_STRING is
assumed to be a collection of octets. To indicate that all bits are used, a byte of zero is
prepended. If a raw bit-string is needed, a new function like ASN1PushInteger() would be
needed. */
/* Return Value Meaning */
/* > 0 number of octets in the encapsulation */
/* == 0 failure */
UINT16
ASN1EndEncapsulation(
ASN1MarshalContext *ctx,
BYTE tag
)
{
// only add a leading zero for an encapsulated BIT STRING
if (tag == ASN1_BITSTRING)
ASN1PushByte(ctx, 0);
ASN1PushTagAndLength(ctx, tag, ctx->end - ctx->offset);
return ASN1EndMarshalContext(ctx);
}
/* 10.2.23.3.6 ASN1PushByte() */
BOOL
ASN1PushByte(
ASN1MarshalContext *ctx,
BYTE b
)
{
if(ctx->offset > 0)
{
ctx->offset -= 1;
if(ctx->buffer)
ctx->buffer[ctx->offset] = b;
return TRUE;
}
ctx->offset = -1;
return FALSE;
}
/* 10.2.23.3.7 ASN1PushBytes() */
/* Push some raw bytes onto the buffer. count cannot be zero. */
/* Return Value Meaning */
/* > 0 count bytes */
/* == 0 failure unless count was zero */
INT16
ASN1PushBytes(
ASN1MarshalContext *ctx,
INT16 count,
const BYTE *buffer
)
{
// make sure that count is not negative which would mess up the math; and that
// if there is a count, there is a buffer
VERIFY((count >= 0) && ((buffer != NULL) || (count == 0)));
// back up the offset to determine where the new octets will get pushed
ctx->offset -= count;
// can't go negative
VERIFY(ctx->offset >= 0);
// if there are buffers, move the data, otherwise, assume that this is just a
// test.
if(count && buffer && ctx->buffer)
MemoryCopy(&ctx->buffer[ctx->offset], buffer, count);
return count;
Error:
ctx->offset = -1;
return 0;
}
/* 10.2.23.3.8 ASN1PushNull() */
/* Return Value Meaning */
/* > 0 count bytes */
/* == 0 failure unless count was zero */
INT16
ASN1PushNull(
ASN1MarshalContext *ctx
)
{
ASN1PushByte(ctx, 0);
ASN1PushByte(ctx, ASN1_NULL);
return (ctx->offset >= 0) ? 2 : 0;
}
/* 10.2.23.3.9 ASN1PushLength() */
/* Push a length value. This will only handle length values that fit in an INT16. */
/* Return Value Meaning */
/* > 0 number of bytes added */
/* == 0 failure */
INT16
ASN1PushLength(
ASN1MarshalContext *ctx,
INT16 len
)
{
UINT16 start = ctx->offset;
VERIFY(len >= 0);
if(len <= 127)
ASN1PushByte(ctx, (BYTE)len);
else
{
ASN1PushByte(ctx, (BYTE)(len & 0xFF));
len >>= 8;
if(len == 0)
ASN1PushByte(ctx, 0x81);
else
{
ASN1PushByte(ctx, (BYTE)(len));
ASN1PushByte(ctx, 0x82);
}
}
goto Exit;
Error:
ctx->offset = -1;
Exit:
return (ctx->offset > 0) ? start - ctx->offset : 0;
}
/* 10.2.23.3.10 ASN1PushTagAndLength() */
/* Return Value Meaning */
/* > 0 number of bytes added */
/* == 0 failure */
INT16
ASN1PushTagAndLength(
ASN1MarshalContext *ctx,
BYTE tag,
INT16 length
)
{
INT16 bytes;
bytes = ASN1PushLength(ctx, length);
bytes += (INT16)ASN1PushByte(ctx, tag);
return (ctx->offset < 0) ? 0 : bytes;
}
/* 10.2.23.3.11 ASN1PushTaggedOctetString() */
/* This function will push a random octet string. */
/* Return Value Meaning */
/* > 0 number of bytes added */
/* == 0 failure */
INT16
ASN1PushTaggedOctetString(
ASN1MarshalContext *ctx,
INT16 size,
const BYTE *string,
BYTE tag
)
{
ASN1PushBytes(ctx, size, string);
// PushTagAndLenght just tells how many octets it added so the total size of this
// element is the sum of those octets and input size.
size += ASN1PushTagAndLength(ctx, tag, size);
return size;
}
/* 10.2.23.3.12 ASN1PushUINT() */
/* This function pushes an native-endian integer value. This just changes a native-endian integer
into a big-endian byte string and calls ASN1PushInteger(). That function will remove leading
zeros and make sure that the number is positive. */
/* Return Value Meaning */
/* > 0 count bytes */
/* == 0 failure unless count was zero */
INT16
ASN1PushUINT(
ASN1MarshalContext *ctx,
UINT32 integer
)
{
BYTE marshaled[4];
UINT32_TO_BYTE_ARRAY(integer, marshaled);
return ASN1PushInteger(ctx, 4, marshaled);
}
/* 10.2.23.3.13 ASN1PushInteger */
/* Push a big-endian integer on the end of the buffer */
/* Return Value Meaning */
/* > 0 the number of bytes marshaled for the integer */
/* == 0 failure */
INT16
ASN1PushInteger(
ASN1MarshalContext *ctx, // IN/OUT: buffer context
INT16 iLen, // IN: octets of the integer
BYTE *integer // IN: big-endian integer
)
{
// no leading 0's
while((*integer == 0) && (--iLen > 0))
integer++;
// Move the bytes to the buffer
ASN1PushBytes(ctx, iLen, integer);
// if needed, add a leading byte of 0 to make the number positive
if(*integer & 0x80)
iLen += (INT16)ASN1PushByte(ctx, 0);
// PushTagAndLenght just tells how many octets it added so the total size of this
// element is the sum of those octets and the adjusted input size.
iLen += ASN1PushTagAndLength(ctx, ASN1_INTEGER, iLen);
return iLen;
}
/* 10.2.23.3.14 ASN1PushOID() */
/* This function is used to add an OID. An OID is 0x06 followed by a byte of size followed by size
bytes. This is used to avoid having to do anything special in the definition of an OID. */
/* Return Value Meaning */
/* > 0 the number of bytes marshaled for the integer */
/* == 0 failure */
INT16
ASN1PushOID(
ASN1MarshalContext *ctx,
const BYTE *OID
)
{
if((*OID == ASN1_OBJECT_IDENTIFIER) && ((OID[1] & 0x80) == 0))
{
return ASN1PushBytes(ctx, OID[1] + 2, OID);
}
ctx->offset = -1;
return 0;
}

137
src/tpm2/TpmAsn1.h Normal file
View File

@ -0,0 +1,137 @@
/********************************************************************************/
/* */
/* Macro and Structure Definitions for the X509 Commands and Functions. */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id$ */
/* */
/* Licenses and Notices */
/* */
/* 1. Copyright Licenses: */
/* */
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
/* this specification (the "Source Code") a worldwide, irrevocable, */
/* nonexclusive, royalty free, copyright license to reproduce, create */
/* derivative works, distribute, display and perform the Source Code and */
/* derivative works thereof, and to grant others the rights granted herein. */
/* */
/* - The TCG grants to the user of the other parts of the specification */
/* (other than the Source Code) the rights to reproduce, distribute, */
/* display, and perform the specification solely for the purpose of */
/* developing products based on such documents. */
/* */
/* 2. Source Code Distribution Conditions: */
/* */
/* - Redistributions of Source Code must retain the above copyright licenses, */
/* this list of conditions and the following disclaimers. */
/* */
/* - Redistributions in binary form must reproduce the above copyright */
/* licenses, this list of conditions and the following disclaimers in the */
/* documentation and/or other materials provided with the distribution. */
/* */
/* 3. Disclaimers: */
/* */
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
/* information on specification licensing rights available through TCG */
/* membership agreements. */
/* */
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
/* */
/* - Without limitation, TCG and its members and licensors disclaim all */
/* liability, including liability for infringement of any proprietary */
/* rights, relating to use of information in this specification and to the */
/* implementation of this specification, and TCG disclaims all liability for */
/* cost of procurement of substitute goods or services, lost profits, loss */
/* of use, loss of data or any incidental, consequential, direct, indirect, */
/* or special damages, whether under contract, tort, warranty or otherwise, */
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2019 */
/* */
/********************************************************************************/
// 10.1.15 TpmAsn1.h
// 10.1.15.1 Introduction
// This file contains the macro and structure definitions for the X509 commands and functions.
#ifndef _TPMASN1_H_
#define _TPMASN1_H_
// 10.1.15.2 Includes
#include "Tpm.h"
#include "OIDS.h"
// 10.1.15.3 Defined Constants
// 10.1.15.3.1 ASN.1 Universal Types (Class 00b
#define ASN1_EOC 0x00
#define ASN1_BOOLEAN 0x01
#define ASN1_INTEGER 0x02
#define ASN1_BITSTRING 0x03
#define ASN1_OCTET_STRING 0x04
#define ASN1_NULL 0x05
#define ASN1_OBJECT_IDENTIFIER 0x06
#define ASN1_OBJECT_DESCRIPTOR 0x07
#define ASN1_EXTERNAL 0x08
#define ASN1_REAL 0x09
#define ASN1_ENUMERATED 0x0A
#define ASN1_EMBEDDED 0x0B
#define ASN1_UTF8String 0x0C
#define ASN1_RELATIVE_OID 0x0D
#define ASN1_SEQUENCE 0x10 // Primitive + Constructed + 0x10
#define ASN1_SET 0x11 // Primitive + Constructed + 0x11
#define ASN1_NumericString 0x12
#define ASN1_PrintableString 0x13
#define ASN1_T61String 0x14
#define ASN1_VideoString 0x15
#define ASN1_IA5String 0x16
#define ASN1_UTCTime 0x17
#define ASN1_GeneralizeTime 0x18
#define ASN1_VisibleString 0x1A
#define ASN1_GeneralString 0x1B
#define ASN1_UniversalString 0x1C
#define ASN1_CHARACTER STRING 0x1D
#define ASN1_BMPString 0x1E
#define ASN1_CONSTRUCTED 0x20
#define ASN1_APPLICAIION_SPECIFIC 0xA0
#define ASN1_CONSTRUCTED_SEQUENCE (ASN1_SEQUENCE + ASN1_CONSTRUCTED)
#define MAX_DEPTH 10 // maximum push depth for marshaling context.
// 10.1.15.4 Macros
// 10.1.15.4.1 Unmarshaling Macros
#ifndef VERIFY
#define VERIFY(_X_) {if(!(_X_)) goto Error; }
#endif
// Checks the validity of the size making sure that there is no wrap around
#define CHECK_SIZE(context, length) \
VERIFY( (((length) + (context)->offset) >= (context)->offset) \
&& (((length) + (context)->offset) <= (context)->size))
#define NEXT_OCTET(context) ((context)->buffer[(context)->offset++])
#define PEEK_NEXT(context) ((context)->buffer[(context)->offset])
// 10.1.15.4.2 Marshaling Macros Marshaling works in reverse order. The offset is set to the top of
// the buffer and, as the buffer is filled, offset counts down to zero. When the full thing is
// encoded it can be moved to the top of the buffer. This happens when the last context is closed
// (when the
#define CHECK_SPACE(context, length) VERIFY(context->offset > length)
// 10.1.15.5 Structures
typedef struct ASN1UnmarshalContext {
BYTE *buffer; // pointer to the buffer
INT16 size; // size of the buffer (a negative number indicates
// a parsing failure).
INT16 offset; // current offset into the buffer (a negative number
// indicates a parsing failure). Not used
BYTE tag; // The last unmarshaled tag
} ASN1UnmarshalContext;
typedef struct ASN1MarshalContext {
BYTE *buffer; // pointer to the start of the buffer
INT16 offset; // place on the top where the last entry was added
// items are added from the bottom up.
INT16 end; // the end offset of the current value
INT16 depth; // how many pushed end values.
INT16 ends[MAX_DEPTH];
} ASN1MarshalContext;
#endif // _TPMASN1_H_

152
src/tpm2/TpmAsn1_fp.h Normal file
View File

@ -0,0 +1,152 @@
/********************************************************************************/
/* */
/* TPM ASN.1 */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id$ */
/* */
/* Licenses and Notices */
/* */
/* 1. Copyright Licenses: */
/* */
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
/* this specification (the "Source Code") a worldwide, irrevocable, */
/* nonexclusive, royalty free, copyright license to reproduce, create */
/* derivative works, distribute, display and perform the Source Code and */
/* derivative works thereof, and to grant others the rights granted herein. */
/* */
/* - The TCG grants to the user of the other parts of the specification */
/* (other than the Source Code) the rights to reproduce, distribute, */
/* display, and perform the specification solely for the purpose of */
/* developing products based on such documents. */
/* */
/* 2. Source Code Distribution Conditions: */
/* */
/* - Redistributions of Source Code must retain the above copyright licenses, */
/* this list of conditions and the following disclaimers. */
/* */
/* - Redistributions in binary form must reproduce the above copyright */
/* licenses, this list of conditions and the following disclaimers in the */
/* documentation and/or other materials provided with the distribution. */
/* */
/* 3. Disclaimers: */
/* */
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
/* information on specification licensing rights available through TCG */
/* membership agreements. */
/* */
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
/* */
/* - Without limitation, TCG and its members and licensors disclaim all */
/* liability, including liability for infringement of any proprietary */
/* rights, relating to use of information in this specification and to the */
/* implementation of this specification, and TCG disclaims all liability for */
/* cost of procurement of substitute goods or services, lost profits, loss */
/* of use, loss of data or any incidental, consequential, direct, indirect, */
/* or special damages, whether under contract, tort, warranty or otherwise, */
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2019 */
/* */
/********************************************************************************/
#ifndef TPMASN1_FP_H
#define TPMASN1_FP_H
BOOL
ASN1UnmarshalContextInitialize(
ASN1UnmarshalContext *ctx,
INT16 size,
BYTE *buffer
);
INT16
ASN1DecodeLength(
ASN1UnmarshalContext *ctx
);
INT16
ASN1NextTag(
ASN1UnmarshalContext *ctx
);
BOOL
ASN1GetBitStringValue(
ASN1UnmarshalContext *ctx,
UINT32 *val
);
void
ASN1InitialializeMarshalContext(
ASN1MarshalContext *ctx,
INT16 length,
BYTE *buffer
);
void
ASN1StartMarshalContext(
ASN1MarshalContext *ctx
);
INT16
ASN1EndMarshalContext(
ASN1MarshalContext *ctx
);
UINT16
ASN1EndEncapsulation(
ASN1MarshalContext *ctx,
BYTE tag
);
BOOL
ASN1PushByte(
ASN1MarshalContext *ctx,
BYTE b
);
INT16
ASN1PushBytes(
ASN1MarshalContext *ctx,
INT16 count,
const BYTE *buffer
);
INT16
ASN1PushNull(
ASN1MarshalContext *ctx
);
INT16
ASN1PushLength(
ASN1MarshalContext *ctx,
INT16 len
);
INT16
ASN1PushTagAndLength(
ASN1MarshalContext *ctx,
BYTE tag,
INT16 length
);
INT16
ASN1PushTaggedOctetString(
ASN1MarshalContext *ctx,
INT16 size,
const BYTE *string,
BYTE tag
);
INT16
ASN1PushUINT(
ASN1MarshalContext *ctx,
UINT32 integer
);
INT16
ASN1PushInteger(
ASN1MarshalContext *ctx, // IN/OUT: buffer context
INT16 iLen, // IN: octets of the integer
BYTE *integer // IN: big-endian integer
);
INT16
ASN1PushOID(
ASN1MarshalContext *ctx,
const BYTE *OID
);
#endif