mirror of
https://github.com/stefanberger/libtpms
synced 2026-08-24 01:23:33 +00:00
tpm2: rev155: Add ASN.1 related code
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
parent
e5a67ccde9
commit
83221ed68e
@ -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
499
src/tpm2/TpmAsn1.c
Normal 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
137
src/tpm2/TpmAsn1.h
Normal 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
152
src/tpm2/TpmAsn1_fp.h
Normal 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
|
||||
Loading…
Reference in New Issue
Block a user