• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "X509.h"
38 #include "OIDs.h"
39 #include "TpmASN1_fp.h"
40 #include "X509_ECC_fp.h"
41 #include "X509_spt_fp.h"
42 #include "CryptHash_fp.h"
43 
44 //** Functions
45 
46 //*** X509PushPoint()
47 // This seems like it might be used more than once so...
48 //  Return Type: INT16
49 //      > 0         number of bytes added
50 //     == 0         failure
51 INT16
X509PushPoint(ASN1MarshalContext * ctx,TPMS_ECC_POINT * p)52 X509PushPoint(
53     ASN1MarshalContext      *ctx,
54     TPMS_ECC_POINT          *p
55 )
56 {
57     // Push a bit string containing the public key. For now, push the x, and y
58     // coordinates of the public point, bottom up
59     ASN1StartMarshalContext(ctx); // BIT STRING
60     {
61         ASN1PushBytes(ctx, p->y.t.size, p->y.t.buffer);
62         ASN1PushBytes(ctx, p->x.t.size, p->x.t.buffer);
63         ASN1PushByte(ctx, 0x04);
64     }
65     return ASN1EndEncapsulation(ctx, ASN1_BITSTRING); // Ends BIT STRING
66 }
67 
68 //*** X509AddSigningAlgorithmECC()
69 // This creates the singing algorithm data.
70 //  Return Type: INT16
71 //      > 0         number of bytes added
72 //     == 0         failure
73 INT16
X509AddSigningAlgorithmECC(OBJECT * signKey,TPMT_SIG_SCHEME * scheme,ASN1MarshalContext * ctx)74 X509AddSigningAlgorithmECC(
75     OBJECT              *signKey,
76     TPMT_SIG_SCHEME     *scheme,
77     ASN1MarshalContext  *ctx
78 )
79 {
80     PHASH_DEF            hashDef = CryptGetHashDef(scheme->details.any.hashAlg);
81 //
82     NOT_REFERENCED(signKey);
83     // If the desired hashAlg definition wasn't found...
84     if(hashDef->hashAlg != scheme->details.any.hashAlg)
85         return 0;
86 
87     switch(scheme->scheme)
88     {
89 #if ALG_ECDSA
90         case TPM_ALG_ECDSA:
91             // Make sure that we have an OID for this hash and ECC
92             if((hashDef->ECDSA)[0] != ASN1_OBJECT_IDENTIFIER)
93                 break;
94             // if this is just an implementation check, indicate that this
95             // combination is supported
96             if(!ctx)
97                 return 1;
98             ASN1StartMarshalContext(ctx);
99             ASN1PushOID(ctx, hashDef->ECDSA);
100             return ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE);
101 #endif //  ALG_ECDSA
102         default:
103             break;
104     }
105     return 0;
106 }
107 
108 
109 //*** X509AddPublicECC()
110 // This function will add the publicKey description to the DER data. If ctx is
111 // NULL, then no data is transferred and this function will indicate if the TPM
112 // has the values for DER-encoding of the public key.
113 //  Return Type: INT16
114 //      > 0         number of bytes added
115 //     == 0         failure
116 INT16
X509AddPublicECC(OBJECT * object,ASN1MarshalContext * ctx)117 X509AddPublicECC(
118     OBJECT                *object,
119     ASN1MarshalContext    *ctx
120 )
121 {
122     const BYTE      *curveOid =
123         CryptEccGetOID(object->publicArea.parameters.eccDetail.curveID);
124     if((curveOid == NULL) || (*curveOid != ASN1_OBJECT_IDENTIFIER))
125         return 0;
126 //
127 //
128 //  SEQUENCE (2 elem) 1st
129 //    SEQUENCE (2 elem) 2nd
130 //      OBJECT IDENTIFIER 1.2.840.10045.2.1 ecPublicKey (ANSI X9.62 public key type)
131 //      OBJECT IDENTIFIER 1.2.840.10045.3.1.7 prime256v1 (ANSI X9.62 named curve)
132 //    BIT STRING (520 bit) 000001001010000111010101010111001001101101000100000010...
133 //
134     // If this is a check to see if the key can be encoded, it can.
135     // Need to mark the end sequence
136     if(ctx == NULL)
137         return 1;
138     ASN1StartMarshalContext(ctx); // SEQUENCE (2 elem) 1st
139     {
140         X509PushPoint(ctx, &object->publicArea.unique.ecc); // BIT STRING
141         ASN1StartMarshalContext(ctx); // SEQUENCE (2 elem) 2nd
142         {
143             ASN1PushOID(ctx, curveOid); // curve dependent
144             ASN1PushOID(ctx, OID_ECC_PUBLIC); // (1.2.840.10045.2.1)
145         }
146         ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE); // Ends SEQUENCE 2nd
147     }
148     return ASN1EndEncapsulation(ctx, ASN1_CONSTRUCTED_SEQUENCE); // Ends SEQUENCE 1st
149 }
150