1 /* Microsoft Reference Implementation for TPM 2.0
2 *
3 * The copyright in this software is being made available under the BSD License,
4 * included below. This software may be subject to other third party and
5 * contributor rights, including patent rights, and no such rights are granted
6 * under this license.
7 *
8 * Copyright (c) Microsoft Corporation
9 *
10 * All rights reserved.
11 *
12 * BSD License
13 *
14 * Redistribution and use in source and binary forms, with or without modification,
15 * are permitted provided that the following conditions are met:
16 *
17 * Redistributions of source code must retain the above copyright notice, this list
18 * of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright notice, this
21 * list of conditions and the following disclaimer in the documentation and/or
22 * other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 //** Includes
36 #include "Tpm.h"
37 #define _OIDS_
38 #include "OIDs.h"
39 #include "TpmASN1.h"
40 #include "TpmASN1_fp.h"
41
42 //** Unmarshaling Functions
43
44 //*** ASN1UnmarshalContextInitialize()
45 // Function does standard initialization of a context.
46 // Return Type: BOOL
47 // TRUE(1) success
48 // FALSE(0) failure
49 BOOL
ASN1UnmarshalContextInitialize(ASN1UnmarshalContext * ctx,INT16 size,BYTE * buffer)50 ASN1UnmarshalContextInitialize(
51 ASN1UnmarshalContext *ctx,
52 INT16 size,
53 BYTE *buffer
54 )
55 {
56 VERIFY(buffer != NULL);
57 VERIFY(size > 0);
58 ctx->buffer = buffer;
59 ctx->size = size;
60 ctx->offset = 0;
61 ctx->tag = 0xFF;
62 return TRUE;
63 Error:
64 return FALSE;
65 }
66
67 //***ASN1DecodeLength()
68 // This function extracts the length of an element from 'buffer' starting at 'offset'.
69 // Return Type: UINT16
70 // >=0 the extracted length
71 // <0 an error
72 INT16
ASN1DecodeLength(ASN1UnmarshalContext * ctx)73 ASN1DecodeLength(
74 ASN1UnmarshalContext *ctx
75 )
76 {
77 BYTE first; // Next octet in buffer
78 INT16 value;
79 //
80 VERIFY(ctx->offset < ctx->size);
81 first = NEXT_OCTET(ctx);
82 // If the number of octets of the entity is larger than 127, then the first octet
83 // is the number of octets in the length specifier.
84 if(first >= 0x80)
85 {
86 // Make sure that this length field is contained with the structure being
87 // parsed
88 CHECK_SIZE(ctx, (first & 0x7F));
89 if(first == 0x82)
90 {
91 // Two octets of size
92 // get the next value
93 value = (INT16)NEXT_OCTET(ctx);
94 // Make sure that the result will fit in an INT16
95 VERIFY(value < 0x0080);
96 // Shift up and add next octet
97 value = (value << 8) + NEXT_OCTET(ctx);
98 }
99 else if(first == 0x81)
100 value = NEXT_OCTET(ctx);
101 // Sizes larger than will fit in a INT16 are an error
102 else
103 goto Error;
104 }
105 else
106 value = first;
107 // Make sure that the size defined something within the current context
108 CHECK_SIZE(ctx, value);
109 return value;
110 Error:
111 ctx->size = -1; // Makes everything fail from now on.
112 return -1;
113 }
114
115 //***ASN1NextTag()
116 // This function extracts the next type from 'buffer' starting at 'offset'.
117 // It advances 'offset' as it parses the type and the length of the type. It returns
118 // the length of the type. On return, the 'length' octets starting at 'offset' are the
119 // octets of the type.
120 // Return Type: UINT
121 // >=0 the number of octets in 'type'
122 // <0 an error
123 INT16
ASN1NextTag(ASN1UnmarshalContext * ctx)124 ASN1NextTag(
125 ASN1UnmarshalContext *ctx
126 )
127 {
128 // A tag to get?
129 VERIFY(ctx->offset < ctx->size);
130 // Get it
131 ctx->tag = NEXT_OCTET(ctx);
132 // Make sure that it is not an extended tag
133 VERIFY((ctx->tag & 0x1F) != 0x1F);
134 // Get the length field and return that
135 return ASN1DecodeLength(ctx);
136
137 Error:
138 // Attempt to read beyond the end of the context or an illegal tag
139 ctx->size = -1; // Persistent failure
140 ctx->tag = 0xFF;
141 return -1;
142 }
143
144
145 //*** ASN1GetBitStringValue()
146 // Try to parse a bit string of up to 32 bits from a value that is expected to be
147 // a bit string. The bit string is left justified so that the MSb of the input is
148 // the MSb of the returned value.
149 // If there is a general parsing error, the context->size is set to -1.
150 // Return Type: BOOL
151 // TRUE(1) success
152 // FALSE(0) failure
153 BOOL
ASN1GetBitStringValue(ASN1UnmarshalContext * ctx,UINT32 * val)154 ASN1GetBitStringValue(
155 ASN1UnmarshalContext *ctx,
156 UINT32 *val
157 )
158 {
159 int shift;
160 INT16 length;
161 UINT32 value = 0;
162 int inputBits;
163 //
164 length = ASN1NextTag(ctx);
165 VERIFY(length >= 1);
166 VERIFY(ctx->tag == ASN1_BITSTRING);
167 // Get the shift value for the bit field (how many bits to lop off of the end)
168 shift = NEXT_OCTET(ctx);
169 length--;
170 // Get the number of bits in the input
171 inputBits = (8 * length) - shift;
172 // the shift count has to make sense
173 VERIFY((shift < 8) && ((length > 0) || (shift == 0)));
174 // if there are any bytes left
175 for(; length > 1; length--)
176 {
177
178 // for all but the last octet, just shift and add the new octet
179 VERIFY((value & 0xFF000000) == 0); // can't loose significant bits
180 value = (value << 8) + NEXT_OCTET(ctx);
181
182 }
183 if(length == 1)
184 {
185 // for the last octet, just shift the accumulated value enough to
186 // accept the significant bits in the last octet and shift the last
187 // octet down
188 VERIFY(((value & (0xFF000000 << (8 - shift)))) == 0);
189 value = (value << (8 - shift)) + (NEXT_OCTET(ctx) >> shift);
190
191 }
192 // 'Left justify' the result
193 if(inputBits > 0)
194 value <<= (32 - inputBits);
195 *val = value;
196 return TRUE;
197 Error:
198 ctx->size = -1;
199 return FALSE;
200 }
201
202 //*******************************************************************
203 //** Marshaling Functions
204 //*******************************************************************
205
206 //*** Introduction
207 // Marshaling of an ASN.1 structure is accomplished from the bottom up. That is,
208 // the things that will be at the end of the structure are added last. To manage the
209 // collecting of the relative sizes, start a context for the outermost container, if
210 // there is one, and then placing items in from the bottom up. If the bottom-most
211 // item is also within a structure, create a nested context by calling
212 // ASN1StartMarshalingContext().
213 //
214 // The context control structure contains a 'buffer' pointer, an 'offset', an 'end'
215 // and a stack. 'offset' is the offset from the start of the buffer of the last added
216 // byte. When 'offset' reaches 0, the buffer is full. 'offset' is a signed value so
217 // that, when it becomes negative, there is an overflow. Only two functions are
218 // allowed to move bytes into the buffer: ASN1PushByte() and ASN1PushBytes(). These
219 // functions make sure that no data is written beyond the end of the buffer.
220 //
221 // When a new context is started, the current value of 'end' is pushed
222 // on the stack and 'end' is set to 'offset. As bytes are added, offset gets smaller.
223 // At any time, the count of bytes in the current context is simply 'end' - 'offset'.
224 //
225 // Since starting a new context involves setting 'end' = 'offset', the number of bytes
226 // in the context starts at 0. The nominal way of ending a context is to use
227 // 'end' - 'offset' to set the length value, and then a tag is added to the buffer.
228 // Then the previous 'end' value is popped meaning that the context just ended
229 // becomes a member of the now current context.
230 //
231 // The nominal strategy for building a completed ASN.1 structure is to push everything
232 // into the buffer and then move everything to the start of the buffer. The move is
233 // simple as the size of the move is the initial 'end' value minus the final 'offset'
234 // value. The destination is 'buffer' and the source is 'buffer' + 'offset'. As Skippy
235 // would say "Easy peasy, Joe."
236 //
237 // It is not necessary to provide a buffer into which the data is placed. If no buffer
238 // is provided, then the marshaling process will return values needed for marshaling.
239 // On strategy for filling the buffer would be to execute the process for building
240 // the structure without using a buffer. This would return the overall size of the
241 // structure. Then that amount of data could be allocated for the buffer and the fill
242 // process executed again with the data going into the buffer. At the end, the data
243 // would be in its final resting place.
244
245 //*** ASN1InitialializeMarshalContext()
246 // This creates a structure for handling marshaling of an ASN.1 formatted data
247 // structure.
248 void
ASN1InitialializeMarshalContext(ASN1MarshalContext * ctx,INT16 length,BYTE * buffer)249 ASN1InitialializeMarshalContext(
250 ASN1MarshalContext *ctx,
251 INT16 length,
252 BYTE *buffer
253 )
254 {
255 ctx->buffer = buffer;
256 if(buffer)
257 ctx->offset = length;
258 else
259 ctx->offset = INT16_MAX;
260 ctx->end = ctx->offset;
261 ctx->depth = -1;
262 }
263
264 //*** ASN1StartMarshalContext()
265 // This starts a new constructed element. It is constructed on 'top' of the value
266 // that was previously placed in the structure.
267 void
ASN1StartMarshalContext(ASN1MarshalContext * ctx)268 ASN1StartMarshalContext(
269 ASN1MarshalContext *ctx
270 )
271 {
272 pAssert((ctx->depth + 1) < MAX_DEPTH);
273 ctx->depth++;
274 ctx->ends[ctx->depth] = ctx->end;
275 ctx->end = ctx->offset;
276 }
277
278 //*** ASN1EndMarshalContext()
279 // This function restores the end pointer for an encapsulating structure.
280 // Return Type: INT16
281 // > 0 the size of the encapsulated structure that was just ended
282 // <= 0 an error
283 INT16
ASN1EndMarshalContext(ASN1MarshalContext * ctx)284 ASN1EndMarshalContext(
285 ASN1MarshalContext *ctx
286 )
287 {
288 INT16 length;
289 pAssert(ctx->depth >= 0);
290 length = ctx->end - ctx->offset;
291 ctx->end = ctx->ends[ctx->depth--];
292 if((ctx->depth == -1) && (ctx->buffer))
293 {
294 MemoryCopy(ctx->buffer, ctx->buffer + ctx->offset, ctx->end - ctx->offset);
295 }
296 return length;
297 }
298
299
300 //***ASN1EndEncapsulation()
301 // This function puts a tag and length in the buffer. In this function, an embedded
302 // BIT_STRING is assumed to be a collection of octets. To indicate that all bits
303 // are used, a byte of zero is prepended. If a raw bit-string is needed, a new
304 // function like ASN1PushInteger() would be needed.
305 // Return Type: INT16
306 // > 0 number of octets in the encapsulation
307 // == 0 failure
308 UINT16
ASN1EndEncapsulation(ASN1MarshalContext * ctx,BYTE tag)309 ASN1EndEncapsulation(
310 ASN1MarshalContext *ctx,
311 BYTE tag
312 )
313 {
314 // only add a leading zero for an encapsulated BIT STRING
315 if (tag == ASN1_BITSTRING)
316 ASN1PushByte(ctx, 0);
317 ASN1PushTagAndLength(ctx, tag, ctx->end - ctx->offset);
318 return ASN1EndMarshalContext(ctx);
319 }
320
321 //*** ASN1PushByte()
322 BOOL
ASN1PushByte(ASN1MarshalContext * ctx,BYTE b)323 ASN1PushByte(
324 ASN1MarshalContext *ctx,
325 BYTE b
326 )
327 {
328 if(ctx->offset > 0)
329 {
330 ctx->offset -= 1;
331 if(ctx->buffer)
332 ctx->buffer[ctx->offset] = b;
333 return TRUE;
334 }
335 ctx->offset = -1;
336 return FALSE;
337 }
338
339 //*** ASN1PushBytes()
340 // Push some raw bytes onto the buffer. 'count' cannot be zero.
341 // Return Type: IN16
342 // > 0 count bytes
343 // == 0 failure unless count was zero
344 INT16
ASN1PushBytes(ASN1MarshalContext * ctx,INT16 count,const BYTE * buffer)345 ASN1PushBytes(
346 ASN1MarshalContext *ctx,
347 INT16 count,
348 const BYTE *buffer
349 )
350 {
351 // make sure that count is not negative which would mess up the math; and that
352 // if there is a count, there is a buffer
353 VERIFY((count >= 0) && ((buffer != NULL) || (count == 0)));
354 // back up the offset to determine where the new octets will get pushed
355 ctx->offset -= count;
356 // can't go negative
357 VERIFY(ctx->offset >= 0);
358 // if there are buffers, move the data, otherwise, assume that this is just a
359 // test.
360 if(count && buffer && ctx->buffer)
361 MemoryCopy(&ctx->buffer[ctx->offset], buffer, count);
362 return count;
363 Error:
364 ctx->offset = -1;
365 return 0;
366 }
367
368 //*** ASN1PushNull()
369 // Return Type: IN16
370 // > 0 count bytes
371 // == 0 failure unless count was zero
372 INT16
ASN1PushNull(ASN1MarshalContext * ctx)373 ASN1PushNull(
374 ASN1MarshalContext *ctx
375 )
376 {
377 ASN1PushByte(ctx, 0);
378 ASN1PushByte(ctx, ASN1_NULL);
379 return (ctx->offset >= 0) ? 2 : 0;
380 }
381
382 //*** ASN1PushLength()
383 // Push a length value. This will only handle length values that fit in an INT16.
384 // Return Type: UINT16
385 // > 0 number of bytes added
386 // == 0 failure
387 INT16
ASN1PushLength(ASN1MarshalContext * ctx,INT16 len)388 ASN1PushLength(
389 ASN1MarshalContext *ctx,
390 INT16 len
391 )
392 {
393 UINT16 start = ctx->offset;
394 VERIFY(len >= 0);
395 if(len <= 127)
396 ASN1PushByte(ctx, (BYTE)len);
397 else
398 {
399 ASN1PushByte(ctx, (BYTE)(len & 0xFF));
400 len >>= 8;
401 if(len == 0)
402 ASN1PushByte(ctx, 0x81);
403 else
404 {
405 ASN1PushByte(ctx, (BYTE)(len));
406 ASN1PushByte(ctx, 0x82);
407 }
408 }
409 goto Exit;
410 Error:
411 ctx->offset = -1;
412 Exit:
413 return (ctx->offset > 0) ? start - ctx->offset : 0;
414 }
415
416 //*** ASN1PushTagAndLength()
417 // Return Type: INT16
418 // > 0 number of bytes added
419 // == 0 failure
420 INT16
ASN1PushTagAndLength(ASN1MarshalContext * ctx,BYTE tag,INT16 length)421 ASN1PushTagAndLength(
422 ASN1MarshalContext *ctx,
423 BYTE tag,
424 INT16 length
425 )
426 {
427 INT16 bytes;
428 bytes = ASN1PushLength(ctx, length);
429 bytes += (INT16)ASN1PushByte(ctx, tag);
430 return (ctx->offset < 0) ? 0 : bytes;
431 }
432
433
434 //*** ASN1PushTaggedOctetString()
435 // This function will push a random octet string.
436 // Return Type: INT16
437 // > 0 number of bytes added
438 // == 0 failure
439 INT16
ASN1PushTaggedOctetString(ASN1MarshalContext * ctx,INT16 size,const BYTE * string,BYTE tag)440 ASN1PushTaggedOctetString(
441 ASN1MarshalContext *ctx,
442 INT16 size,
443 const BYTE *string,
444 BYTE tag
445 )
446 {
447 ASN1PushBytes(ctx, size, string);
448 // PushTagAndLenght just tells how many octets it added so the total size of this
449 // element is the sum of those octets and input size.
450 size += ASN1PushTagAndLength(ctx, tag, size);
451 return size;
452 }
453
454 //*** ASN1PushUINT()
455 // This function pushes an native-endian integer value. This just changes a
456 // native-endian integer into a big-endian byte string and calls ASN1PushInteger().
457 // That function will remove leading zeros and make sure that the number is positive.
458 // Return Type: IN16
459 // > 0 count bytes
460 // == 0 failure unless count was zero
461 INT16
ASN1PushUINT(ASN1MarshalContext * ctx,UINT32 integer)462 ASN1PushUINT(
463 ASN1MarshalContext *ctx,
464 UINT32 integer
465 )
466 {
467 BYTE marshaled[4];
468 UINT32_TO_BYTE_ARRAY(integer, marshaled);
469 return ASN1PushInteger(ctx, 4, marshaled);
470 }
471
472 //*** ASN1PushInteger
473 // Push a big-endian integer on the end of the buffer
474 // Return Type: UINT16
475 // > 0 the number of bytes marshaled for the integer
476 // == 0 failure
477 INT16
ASN1PushInteger(ASN1MarshalContext * ctx,INT16 iLen,BYTE * integer)478 ASN1PushInteger(
479 ASN1MarshalContext *ctx, // IN/OUT: buffer context
480 INT16 iLen, // IN: octets of the integer
481 BYTE *integer // IN: big-endian integer
482 )
483 {
484 // no leading 0's
485 while((*integer == 0) && (--iLen > 0))
486 integer++;
487 // Move the bytes to the buffer
488 ASN1PushBytes(ctx, iLen, integer);
489 // if needed, add a leading byte of 0 to make the number positive
490 if(*integer & 0x80)
491 iLen += (INT16)ASN1PushByte(ctx, 0);
492 // PushTagAndLenght just tells how many octets it added so the total size of this
493 // element is the sum of those octets and the adjusted input size.
494 iLen += ASN1PushTagAndLength(ctx, ASN1_INTEGER, iLen);
495 return iLen;
496 }
497
498 //*** ASN1PushOID()
499 // This function is used to add an OID. An OID is 0x06 followed by a byte of size
500 // followed by size bytes. This is used to avoid having to do anything special in the
501 // definition of an OID.
502 // Return Type: UINT16
503 // > 0 the number of bytes marshaled for the integer
504 // == 0 failure
505 INT16
ASN1PushOID(ASN1MarshalContext * ctx,const BYTE * OID)506 ASN1PushOID(
507 ASN1MarshalContext *ctx,
508 const BYTE *OID
509 )
510 {
511 if((*OID == ASN1_OBJECT_IDENTIFIER) && ((OID[1] & 0x80) == 0))
512 {
513 return ASN1PushBytes(ctx, OID[1] + 2, OID);
514 }
515 ctx->offset = -1;
516 return 0;
517 }
518
519
520