Coverage Report

Created: 2026-09-01 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libtpms/src/tpm2/EphemeralCommands.c
Line
Count
Source
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
    pAssert_RC(eccKey != NULL);
104
0
    parms  = &eccKey->publicArea.parameters.eccDetail;
105
106
    // Input key must be an ECC key
107
0
    if(eccKey->publicArea.type != TPM_ALG_ECC)
108
0
  return TPM_RCS_KEY + RC_Commit_signHandle;
109
110
    // This command may only be used with a sign-only key using an anonymous
111
    // scheme.
112
    // NOTE: a sign + decrypt key has no scheme so it will not be an anonymous one
113
    // and an unrestricted sign key might no have a signing scheme but it can't
114
    // be use in Commit()
115
0
    if(!CryptIsSchemeAnonymous(parms->scheme.scheme))
116
0
  return TPM_RCS_SCHEME + RC_Commit_signHandle;
117
118
    // Make sure that both parts of P2 are present if either is present
119
0
    if((in->s2.t.size == 0) != (in->y2.t.size == 0))
120
0
  return TPM_RCS_SIZE + RC_Commit_y2;
121
122
    // Get prime modulus for the curve. This is needed later but getting this now
123
    // allows confirmation that the curve exists.
124
0
    if(!TpmMath_IntTo2B(ExtEcc_CurveGetPrime(parms->curveID), &p.b, 0))
125
0
  return TPM_RCS_KEY + RC_Commit_signHandle;
126
127
    // Get the random value that will be used in the point multiplications
128
    // Note: this does not commit the count.
129
0
    if(!CryptGenerateR(&r, NULL, parms->curveID, &eccKey->name))
130
0
  return TPM_RC_NO_RESULT;
131
132
    // Set up P2 if s2 and Y2 are provided
133
0
    if(in->s2.t.size != 0)
134
0
  {
135
0
      TPM2B_DIGEST x2;
136
137
0
      pP2 = &P2;
138
139
      // copy y2 for P2
140
0
      P2.y = in->y2;
141
142
      // Compute x2  HnameAlg(s2) mod p
143
      //      do the hash operation on s2 with the size of curve 'p'
144
0
      x2.t.size = CryptHashBlock(eccKey->publicArea.nameAlg,
145
0
               in->s2.t.size,
146
0
               in->s2.t.buffer,
147
0
               sizeof(x2.t.buffer),
148
0
               x2.t.buffer);
149
150
      // If there were error returns in the hash routine, indicate a problem
151
      // with the hash algorithm selection
152
0
      if(x2.t.size == 0)
153
0
    return TPM_RCS_HASH + RC_Commit_signHandle;
154
      // The size of the remainder will be same as the size of p. DivideB() will
155
      // pad the results (leading zeros) if necessary to make the size the same
156
0
      P2.x.t.size = p.t.size;
157
      //  set p2.x = hash(s2) mod p
158
0
      if(DivideB(&x2.b, &p.b, NULL, &P2.x.b) != TPM_RC_SUCCESS)
159
0
    return TPM_RC_NO_RESULT;
160
161
0
      if(!CryptEccIsPointOnCurve(parms->curveID, pP2))
162
0
    return TPM_RCS_ECC_POINT + RC_Commit_s2;
163
164
0
      if(eccKey->attributes.publicOnly == SET)
165
0
    return TPM_RCS_KEY + RC_Commit_signHandle;
166
0
  }
167
    // If there is a P1, make sure that it is on the curve
168
    // NOTE: an "empty" point has two UINT16 values which are the size values
169
    // for each of the coordinates.
170
0
    if(in->P1.size > 4)
171
0
  {
172
0
      pP1 = &in->P1.point;
173
0
      if(!CryptEccIsPointOnCurve(parms->curveID, pP1))
174
0
    return TPM_RCS_ECC_POINT + RC_Commit_P1;
175
0
  }
176
177
    // Pass the parameters to CryptCommit.
178
    // The work is not done in-line because it does several point multiplies
179
    // with the same curve.  It saves work by not having to reload the curve
180
    // parameters multiple times.
181
0
    result = CryptEccCommitCompute(&out->K.point,
182
0
           &out->L.point,
183
0
           &out->E.point,
184
0
           parms->curveID,
185
0
           pP1,
186
0
           pP2,
187
0
           &eccKey->sensitive.sensitive.ecc,
188
0
           &r);
189
0
    if(result != TPM_RC_SUCCESS)
190
0
  return result;
191
192
    // The commit computation was successful so complete the commit by setting
193
    // the bit
194
0
    out->counter = CryptCommit();
195
196
0
    return TPM_RC_SUCCESS;
197
0
}
198
199
#endif  // CC_Commit
200
201
#include "Tpm.h"
202
#include "EC_Ephemeral_fp.h"
203
#if CC_EC_Ephemeral  // Conditional expansion of this file
204
TPM_RC
205
TPM2_EC_Ephemeral(
206
      EC_Ephemeral_In     *in,            // IN: input parameter list
207
      EC_Ephemeral_Out    *out            // OUT: output parameter list
208
      )
209
8
{
210
8
    TPM2B_ECC_PARAMETER      r;
211
8
    TPM_RC                   result;
212
213
8
    if(RuntimeProfileRequiresAttributeFlags(&g_RuntimeProfile, // libtpms added begin
214
8
              RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION))
215
0
  return TPM_RC_TYPE;         // libtpms added end
216
217
    //
218
8
    do
219
8
  {
220
      // Get the random value that will be used in the point multiplications
221
      // Note: this does not commit the count.
222
8
      if(!CryptGenerateR(&r, NULL, in->curveID, NULL))
223
0
    return TPM_RC_NO_RESULT;
224
      // do a point multiply
225
8
      result = CryptEccPointMultiply(&out->Q.point, in->curveID, NULL, &r,
226
8
             NULL, NULL);
227
      // commit the count value if either the r value results in the point at
228
      // infinity or if the value is good. The commit on the r value for infinity
229
      // is so that the r value will be skipped.
230
8
      if((result == TPM_RC_SUCCESS) || (result == TPM_RC_NO_RESULT))
231
8
    out->counter = CryptCommit();
232
8
  } while(result == TPM_RC_NO_RESULT);
233
8
    return TPM_RC_SUCCESS;
234
8
}
235
#endif // CC_EC_Ephemeral