Coverage Report

Created: 2025-07-18 06:10

/src/libtpms/src/tpm2/EphemeralCommands.c
Line
Count
Source (jump to first uncovered line)
1
/********************************************************************************/
2
/*                    */
3
/*        Ephemeral EC Keys           */
4
/*           Written by Ken Goldman       */
5
/*           IBM Thomas J. Watson Research Center     */
6
/*                    */
7
/*  Licenses and Notices              */
8
/*                    */
9
/*  1. Copyright Licenses:              */
10
/*                    */
11
/*  - Trusted Computing Group (TCG) grants to the user of the source code in  */
12
/*    this specification (the "Source Code") a worldwide, irrevocable,    */
13
/*    nonexclusive, royalty free, copyright license to reproduce, create  */
14
/*    derivative works, distribute, display and perform the Source Code and */
15
/*    derivative works thereof, and to grant others the rights granted herein.  */
16
/*                    */
17
/*  - The TCG grants to the user of the other parts of the specification  */
18
/*    (other than the Source Code) the rights to reproduce, distribute,   */
19
/*    display, and perform the specification solely for the purpose of    */
20
/*    developing products based on such documents.        */
21
/*                    */
22
/*  2. Source Code Distribution Conditions:         */
23
/*                    */
24
/*  - Redistributions of Source Code must retain the above copyright licenses,  */
25
/*    this list of conditions and the following disclaimers.      */
26
/*                    */
27
/*  - Redistributions in binary form must reproduce the above copyright   */
28
/*    licenses, this list of conditions and the following disclaimers in the  */
29
/*    documentation and/or other materials provided with the distribution.  */
30
/*                    */
31
/*  3. Disclaimers:               */
32
/*                    */
33
/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
34
/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
35
/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
36
/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.   */
37
/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for    */
38
/*  information on specification licensing rights available through TCG   */
39
/*  membership agreements.              */
40
/*                    */
41
/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED   */
42
/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR   */
43
/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR    */
44
/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY    */
45
/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.   */
46
/*                    */
47
/*  - Without limitation, TCG and its members and licensors disclaim all  */
48
/*    liability, including liability for infringement of any proprietary  */
49
/*    rights, relating to use of information in this specification and to the */
50
/*    implementation of this specification, and TCG disclaims all liability for */
51
/*    cost of procurement of substitute goods or services, lost profits, loss   */
52
/*    of use, loss of data or any incidental, consequential, direct, indirect,  */
53
/*    or special damages, whether under contract, tort, warranty or otherwise,  */
54
/*    arising in any way out of use or reliance upon this specification or any  */
55
/*    information herein.             */
56
/*                    */
57
/*  (c) Copyright IBM Corp. and others, 2016 - 2023       */
58
/*                    */
59
/********************************************************************************/
60
61
#include "Tpm.h"
62
#include "Commit_fp.h"
63
#include "TpmMath_Util_fp.h"
64
65
#if CC_Commit  // Conditional expansion of this file
66
67
/*(See part 3 specification)
68
// This command performs the point multiply operations for anonymous signing
69
// scheme.
70
*/
71
//  Return Type: TPM_RC
72
//      TPM_RC_ATTRIBUTES       'keyHandle' references a restricted key that is not a
73
//                              signing key
74
//      TPM_RC_ECC_POINT        either 'P1' or the point derived from 's2' is not on
75
//                              the curve of 'keyHandle'
76
//      TPM_RC_HASH             invalid name algorithm in 'keyHandle'
77
//      TPM_RC_KEY              'keyHandle' does not reference an ECC key
78
//      TPM_RC_SCHEME           the scheme of 'keyHandle' is not an anonymous scheme
79
//      TPM_RC_NO_RESULT        'K', 'L' or 'E' was a point at infinity; or
80
//                              failed to generate "r" value
81
//      TPM_RC_SIZE             's2' is empty but 'y2' is not or 's2' provided but
82
//                              'y2' is not
83
TPM_RC
84
TPM2_Commit(Commit_In*  in,  // IN: input parameter list
85
      Commit_Out* out  // OUT: output parameter list
86
      )
87
0
{
88
0
    OBJECT*             eccKey;
89
0
    TPMS_ECC_POINT      P2;
90
0
    TPMS_ECC_POINT*     pP2 = NULL;
91
0
    TPMS_ECC_POINT*     pP1 = NULL;
92
0
    TPM2B_ECC_PARAMETER r;
93
0
    TPM2B_ECC_PARAMETER p;
94
0
    TPM_RC              result;
95
0
    TPMS_ECC_PARMS*     parms;
96
    // Input Validation
97
98
0
    if(RuntimeProfileRequiresAttributeFlags(&g_RuntimeProfile, // libtpms added begin
99
0
              RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION))
100
0
  return TPM_RC_TYPE;         // libtpms added end
101
102
0
    eccKey = HandleToObject(in->signHandle);
103
0
    parms  = &eccKey->publicArea.parameters.eccDetail;
104
105
    // Input key must be an ECC key
106
0
    if(eccKey->publicArea.type != TPM_ALG_ECC)
107
0
  return TPM_RCS_KEY + RC_Commit_signHandle;
108
109
    // This command may only be used with a sign-only key using an anonymous
110
    // scheme.
111
    // NOTE: a sign + decrypt key has no scheme so it will not be an anonymous one
112
    // and an unrestricted sign key might no have a signing scheme but it can't
113
    // be use in Commit()
114
0
    if(!CryptIsSchemeAnonymous(parms->scheme.scheme))
115
0
  return TPM_RCS_SCHEME + RC_Commit_signHandle;
116
117
    // Make sure that both parts of P2 are present if either is present
118
0
    if((in->s2.t.size == 0) != (in->y2.t.size == 0))
119
0
  return TPM_RCS_SIZE + RC_Commit_y2;
120
121
    // Get prime modulus for the curve. This is needed later but getting this now
122
    // allows confirmation that the curve exists.
123
0
    if(!TpmMath_IntTo2B(ExtEcc_CurveGetPrime(parms->curveID), &p.b, 0))
124
0
  return TPM_RCS_KEY + RC_Commit_signHandle;
125
126
    // Get the random value that will be used in the point multiplications
127
    // Note: this does not commit the count.
128
0
    if(!CryptGenerateR(&r, NULL, parms->curveID, &eccKey->name))
129
0
  return TPM_RC_NO_RESULT;
130
131
    // Set up P2 if s2 and Y2 are provided
132
0
    if(in->s2.t.size != 0)
133
0
  {
134
0
      TPM2B_DIGEST x2;
135
136
0
      pP2 = &P2;
137
138
      // copy y2 for P2
139
0
      P2.y = in->y2;
140
141
      // Compute x2  HnameAlg(s2) mod p
142
      //      do the hash operation on s2 with the size of curve 'p'
143
0
      x2.t.size = CryptHashBlock(eccKey->publicArea.nameAlg,
144
0
               in->s2.t.size,
145
0
               in->s2.t.buffer,
146
0
               sizeof(x2.t.buffer),
147
0
               x2.t.buffer);
148
149
      // If there were error returns in the hash routine, indicate a problem
150
      // with the hash algorithm selection
151
0
      if(x2.t.size == 0)
152
0
    return TPM_RCS_HASH + RC_Commit_signHandle;
153
      // The size of the remainder will be same as the size of p. DivideB() will
154
      // pad the results (leading zeros) if necessary to make the size the same
155
0
      P2.x.t.size = p.t.size;
156
      //  set p2.x = hash(s2) mod p
157
0
      if(DivideB(&x2.b, &p.b, NULL, &P2.x.b) != TPM_RC_SUCCESS)
158
0
    return TPM_RC_NO_RESULT;
159
160
0
      if(!CryptEccIsPointOnCurve(parms->curveID, pP2))
161
0
    return TPM_RCS_ECC_POINT + RC_Commit_s2;
162
163
0
      if(eccKey->attributes.publicOnly == SET)
164
0
    return TPM_RCS_KEY + RC_Commit_signHandle;
165
0
  }
166
    // If there is a P1, make sure that it is on the curve
167
    // NOTE: an "empty" point has two UINT16 values which are the size values
168
    // for each of the coordinates.
169
0
    if(in->P1.size > 4)
170
0
  {
171
0
      pP1 = &in->P1.point;
172
0
      if(!CryptEccIsPointOnCurve(parms->curveID, pP1))
173
0
    return TPM_RCS_ECC_POINT + RC_Commit_P1;
174
0
  }
175
176
    // Pass the parameters to CryptCommit.
177
    // The work is not done in-line because it does several point multiplies
178
    // with the same curve.  It saves work by not having to reload the curve
179
    // parameters multiple times.
180
0
    result = CryptEccCommitCompute(&out->K.point,
181
0
           &out->L.point,
182
0
           &out->E.point,
183
0
           parms->curveID,
184
0
           pP1,
185
0
           pP2,
186
0
           &eccKey->sensitive.sensitive.ecc,
187
0
           &r);
188
0
    if(result != TPM_RC_SUCCESS)
189
0
  return result;
190
191
    // The commit computation was successful so complete the commit by setting
192
    // the bit
193
0
    out->counter = CryptCommit();
194
195
0
    return TPM_RC_SUCCESS;
196
0
}
197
198
#endif  // CC_Commit
199
200
#include "Tpm.h"
201
#include "EC_Ephemeral_fp.h"
202
#if CC_EC_Ephemeral  // Conditional expansion of this file
203
TPM_RC
204
TPM2_EC_Ephemeral(
205
      EC_Ephemeral_In     *in,            // IN: input parameter list
206
      EC_Ephemeral_Out    *out            // OUT: output parameter list
207
      )
208
8
{
209
8
    TPM2B_ECC_PARAMETER      r;
210
8
    TPM_RC                   result;
211
212
8
    if(RuntimeProfileRequiresAttributeFlags(&g_RuntimeProfile, // libtpms added begin
213
8
              RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION))
214
0
  return TPM_RC_TYPE;         // libtpms added end
215
216
    //
217
8
    do
218
8
  {
219
      // Get the random value that will be used in the point multiplications
220
      // Note: this does not commit the count.
221
8
      if(!CryptGenerateR(&r, NULL, in->curveID, NULL))
222
0
    return TPM_RC_NO_RESULT;
223
      // do a point multiply
224
8
      result = CryptEccPointMultiply(&out->Q.point, in->curveID, NULL, &r,
225
8
             NULL, NULL);
226
      // commit the count value if either the r value results in the point at
227
      // infinity or if the value is good. The commit on the r value for infinity
228
      // is so that the r value will be skipped.
229
8
      if((result == TPM_RC_SUCCESS) || (result == TPM_RC_NO_RESULT))
230
8
    out->counter = CryptCommit();
231
8
  } while(result == TPM_RC_NO_RESULT);
232
8
    return TPM_RC_SUCCESS;
233
8
}
234
#endif // CC_EC_Ephemeral