Coverage Report

Created: 2024-07-27 06:30

/src/ibmswtpm2/src/AsymmetricCommands.c
Line
Count
Source (jump to first uncovered line)
1
/********************************************************************************/
2
/*                    */
3
/*        Asymmetric Commands           */
4
/*           Written by Ken Goldman       */
5
/*           IBM Thomas J. Watson Research Center     */
6
/*            $Id: AsymmetricCommands.c 1262 2018-07-11 21:03:43Z kgoldman $  */
7
/*                    */
8
/*  Licenses and Notices              */
9
/*                    */
10
/*  1. Copyright Licenses:              */
11
/*                    */
12
/*  - Trusted Computing Group (TCG) grants to the user of the source code in  */
13
/*    this specification (the "Source Code") a worldwide, irrevocable,    */
14
/*    nonexclusive, royalty free, copyright license to reproduce, create  */
15
/*    derivative works, distribute, display and perform the Source Code and */
16
/*    derivative works thereof, and to grant others the rights granted herein.  */
17
/*                    */
18
/*  - The TCG grants to the user of the other parts of the specification  */
19
/*    (other than the Source Code) the rights to reproduce, distribute,   */
20
/*    display, and perform the specification solely for the purpose of    */
21
/*    developing products based on such documents.        */
22
/*                    */
23
/*  2. Source Code Distribution Conditions:         */
24
/*                    */
25
/*  - Redistributions of Source Code must retain the above copyright licenses,  */
26
/*    this list of conditions and the following disclaimers.      */
27
/*                    */
28
/*  - Redistributions in binary form must reproduce the above copyright   */
29
/*    licenses, this list of conditions and the following disclaimers in the  */
30
/*    documentation and/or other materials provided with the distribution.  */
31
/*                    */
32
/*  3. Disclaimers:               */
33
/*                    */
34
/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
35
/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
36
/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
37
/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.   */
38
/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for    */
39
/*  information on specification licensing rights available through TCG   */
40
/*  membership agreements.              */
41
/*                    */
42
/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED   */
43
/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR   */
44
/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR    */
45
/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY    */
46
/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.   */
47
/*                    */
48
/*  - Without limitation, TCG and its members and licensors disclaim all  */
49
/*    liability, including liability for infringement of any proprietary  */
50
/*    rights, relating to use of information in this specification and to the */
51
/*    implementation of this specification, and TCG disclaims all liability for */
52
/*    cost of procurement of substitute goods or services, lost profits, loss   */
53
/*    of use, loss of data or any incidental, consequential, direct, indirect,  */
54
/*    or special damages, whether under contract, tort, warranty or otherwise,  */
55
/*    arising in any way out of use or reliance upon this specification or any  */
56
/*    information herein.             */
57
/*                    */
58
/*  (c) Copyright IBM Corp. and others, 2016 - 2018       */
59
/*                    */
60
/********************************************************************************/
61
62
#include "Tpm.h"
63
#include "RSA_Encrypt_fp.h"
64
#if CC_RSA_Encrypt  // Conditional expansion of this file
65
#if ALG_RSA
66
TPM_RC
67
TPM2_RSA_Encrypt(
68
     RSA_Encrypt_In      *in,            // IN: input parameter list
69
     RSA_Encrypt_Out     *out            // OUT: output parameter list
70
     )
71
0
{
72
0
    TPM_RC                  result;
73
0
    OBJECT                  *rsaKey;
74
0
    TPMT_RSA_DECRYPT        *scheme;
75
    // Input Validation
76
0
    rsaKey = HandleToObject(in->keyHandle);
77
    // selected key must be an RSA key
78
0
    if(rsaKey->publicArea.type != TPM_ALG_RSA)
79
0
  return TPM_RCS_KEY + RC_RSA_Encrypt_keyHandle;
80
    // selected key must have the decryption attribute
81
0
    if(!IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
82
0
  return TPM_RCS_ATTRIBUTES + RC_RSA_Encrypt_keyHandle;
83
    // Is there a label?
84
0
    if(!IsLabelProperlyFormatted(&in->label.b))
85
0
  return TPM_RCS_VALUE + RC_RSA_Encrypt_label;
86
    // Command Output
87
    // Select a scheme for encryption
88
0
    scheme = CryptRsaSelectScheme(in->keyHandle, &in->inScheme);
89
0
    if(scheme == NULL)
90
0
  return TPM_RCS_SCHEME + RC_RSA_Encrypt_inScheme;
91
    // Encryption.  TPM_RC_VALUE, or TPM_RC_SCHEME errors my be returned buy
92
    // CryptEncyptRSA.
93
0
    out->outData.t.size = sizeof(out->outData.t.buffer);
94
0
    result = CryptRsaEncrypt(&out->outData, &in->message.b, rsaKey, scheme,
95
0
           &in->label.b, NULL);
96
0
    return result;
97
0
}
98
#endif
99
#endif // CC_RSA_Encrypt
100
#include "Tpm.h"
101
#include "RSA_Decrypt_fp.h"
102
#if CC_RSA_Decrypt  // Conditional expansion of this file
103
#if ALG_RSA
104
TPM_RC
105
TPM2_RSA_Decrypt(
106
     RSA_Decrypt_In      *in,            // IN: input parameter list
107
     RSA_Decrypt_Out     *out            // OUT: output parameter list
108
     )
109
0
{
110
0
    TPM_RC                       result;
111
0
    OBJECT                      *rsaKey;
112
0
    TPMT_RSA_DECRYPT            *scheme;
113
    // Input Validation
114
0
    rsaKey = HandleToObject(in->keyHandle);
115
    // The selected key must be an RSA key
116
0
    if(rsaKey->publicArea.type != TPM_ALG_RSA)
117
0
  return TPM_RCS_KEY + RC_RSA_Decrypt_keyHandle;
118
    // The selected key must be an unrestricted decryption key
119
0
    if(IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
120
0
       || !IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
121
0
  return TPM_RCS_ATTRIBUTES + RC_RSA_Decrypt_keyHandle;
122
    // NOTE: Proper operation of this command requires that the sensitive area
123
    // of the key is loaded. This is assured because authorization is required
124
    // to use the sensitive area of the key. In order to check the authorization,
125
    // the sensitive area has to be loaded, even if authorization is with policy.
126
    // If label is present, make sure that it is a NULL-terminated string
127
0
    if(!IsLabelProperlyFormatted(&in->label.b))
128
0
  return TPM_RCS_VALUE + RC_RSA_Decrypt_label;
129
    // Command Output
130
    // Select a scheme for decrypt.
131
0
    scheme = CryptRsaSelectScheme(in->keyHandle, &in->inScheme);
132
0
    if(scheme == NULL)
133
0
  return TPM_RCS_SCHEME + RC_RSA_Decrypt_inScheme;
134
    // Decryption.  TPM_RC_VALUE, TPM_RC_SIZE, and TPM_RC_KEY error may be
135
    // returned by CryptRsaDecrypt.
136
    // NOTE: CryptRsaDecrypt can also return TPM_RC_ATTRIBUTES or TPM_RC_BINDING
137
    // when the key is not a decryption key but that was checked above.
138
0
    out->message.t.size = sizeof(out->message.t.buffer);
139
0
    result = CryptRsaDecrypt(&out->message.b, &in->cipherText.b, rsaKey,
140
0
           scheme, &in->label.b);
141
0
    return result;
142
0
}
143
#endif
144
#endif // CC_RSA_Decrypt
145
#include "Tpm.h"
146
#include "ECDH_KeyGen_fp.h"
147
#if CC_ECDH_KeyGen  // Conditional expansion of this file
148
#if ALG_ECC
149
TPM_RC
150
TPM2_ECDH_KeyGen(
151
     ECDH_KeyGen_In      *in,            // IN: input parameter list
152
     ECDH_KeyGen_Out     *out            // OUT: output parameter list
153
     )
154
0
{
155
0
    OBJECT                  *eccKey;
156
0
    TPM2B_ECC_PARAMETER      sensitive;
157
0
    TPM_RC                   result;
158
    // Input Validation
159
0
    eccKey = HandleToObject(in->keyHandle);
160
    // Referenced key must be an ECC key
161
0
    if(eccKey->publicArea.type != TPM_ALG_ECC)
162
0
  return TPM_RCS_KEY + RC_ECDH_KeyGen_keyHandle;
163
    // Command Output
164
0
    do
165
0
  {
166
0
      TPMT_PUBLIC         *keyPublic = &eccKey->publicArea;
167
      // Create ephemeral ECC key
168
0
      result = CryptEccNewKeyPair(&out->pubPoint.point, &sensitive,
169
0
          keyPublic->parameters.eccDetail.curveID);
170
0
      if(result == TPM_RC_SUCCESS)
171
0
          {
172
              // Compute Z
173
0
              result = CryptEccPointMultiply(&out->zPoint.point,
174
0
                                             keyPublic->parameters.eccDetail.curveID,
175
0
                                             &keyPublic->unique.ecc,
176
0
                                             &sensitive,
177
0
                                             NULL, NULL);
178
        // The point in the key is not on the curve. Indicate
179
        // that the key is bad.
180
0
              if(result == TPM_RC_ECC_POINT)
181
0
                  return TPM_RCS_KEY + RC_ECDH_KeyGen_keyHandle;
182
        // The other possible error from CryptEccPointMultiply is
183
        // TPM_RC_NO_RESULT indicating that the multiplication resulted in
184
        // the point at infinity, so get a new random key and start over
185
        // BTW, this never happens.
186
0
          }
187
0
  } while(result == TPM_RC_NO_RESULT);
188
0
    return result;
189
0
}
190
#endif // ALG_ECC
191
#endif // CC_ECDH_KeyGen
192
#include "Tpm.h"
193
#include "ECDH_ZGen_fp.h"
194
#if CC_ECDH_ZGen  // Conditional expansion of this file
195
#if ALG_ECC
196
TPM_RC
197
TPM2_ECDH_ZGen(
198
         ECDH_ZGen_In    *in,            // IN: input parameter list
199
         ECDH_ZGen_Out   *out            // OUT: output parameter list
200
         )
201
0
{
202
0
    TPM_RC                   result;
203
0
    OBJECT                  *eccKey;
204
    // Input Validation
205
0
    eccKey = HandleToObject(in->keyHandle);
206
    // Selected key must be a non-restricted, decrypt ECC key
207
0
    if(eccKey->publicArea.type != TPM_ALG_ECC)
208
0
  return TPM_RCS_KEY + RC_ECDH_ZGen_keyHandle;
209
    // Selected key needs to be unrestricted with the 'decrypt' attribute
210
0
    if(IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
211
0
       || !IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
212
0
  return TPM_RCS_ATTRIBUTES + RC_ECDH_ZGen_keyHandle;
213
    // Make sure the scheme allows this use
214
0
    if(eccKey->publicArea.parameters.eccDetail.scheme.scheme != TPM_ALG_ECDH
215
0
       &&  eccKey->publicArea.parameters.eccDetail.scheme.scheme != TPM_ALG_NULL)
216
0
  return TPM_RCS_SCHEME + RC_ECDH_ZGen_keyHandle;
217
    // Command Output
218
    // Compute Z. TPM_RC_ECC_POINT or TPM_RC_NO_RESULT may be returned here.
219
0
    result = CryptEccPointMultiply(&out->outPoint.point,
220
0
           eccKey->publicArea.parameters.eccDetail.curveID,
221
0
           &in->inPoint.point,
222
0
           &eccKey->sensitive.sensitive.ecc,
223
0
           NULL, NULL);
224
0
    if(result != TPM_RC_SUCCESS)
225
0
  return RcSafeAddToResult(result, RC_ECDH_ZGen_inPoint);
226
0
    return result;
227
0
}
228
#endif
229
#endif // CC_ECDH_ZGen
230
#include "Tpm.h"
231
#include "ECC_Parameters_fp.h"
232
#if CC_ECC_Parameters  // Conditional expansion of this file
233
#if ALG_ECC
234
TPM_RC
235
TPM2_ECC_Parameters(
236
        ECC_Parameters_In   *in,            // IN: input parameter list
237
        ECC_Parameters_Out  *out            // OUT: output parameter list
238
        )
239
0
{
240
    // Command Output
241
    // Get ECC curve parameters
242
0
    if(CryptEccGetParameters(in->curveID, &out->parameters))
243
0
  return TPM_RC_SUCCESS;
244
0
    else
245
0
  return TPM_RCS_VALUE + RC_ECC_Parameters_curveID;
246
0
}
247
#endif
248
#endif // CC_ECC_Parameters
249
#include "Tpm.h"
250
#include "ZGen_2Phase_fp.h"
251
#if CC_ZGen_2Phase  // Conditional expansion of this file
252
TPM_RC
253
TPM2_ZGen_2Phase(
254
     ZGen_2Phase_In      *in,            // IN: input parameter list
255
     ZGen_2Phase_Out     *out            // OUT: output parameter list
256
     )
257
0
{
258
0
    TPM_RC                   result;
259
0
    OBJECT                  *eccKey;
260
0
    TPM2B_ECC_PARAMETER      r;
261
0
    TPM_ALG_ID               scheme;
262
    // Input Validation
263
0
    eccKey = HandleToObject(in->keyA);
264
    // keyA must be an ECC key
265
0
    if(eccKey->publicArea.type != TPM_ALG_ECC)
266
0
  return TPM_RCS_KEY + RC_ZGen_2Phase_keyA;
267
    // keyA must not be restricted and must be a decrypt key
268
0
    if(IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
269
0
       || !IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
270
0
  return TPM_RCS_ATTRIBUTES + RC_ZGen_2Phase_keyA;
271
    // if the scheme of keyA is TPM_ALG_NULL, then use the input scheme; otherwise
272
    // the input scheme must be the same as the scheme of keyA
273
0
    scheme = eccKey->publicArea.parameters.asymDetail.scheme.scheme;
274
0
    if(scheme != TPM_ALG_NULL)
275
0
  {
276
0
      if(scheme != in->inScheme)
277
0
    return TPM_RCS_SCHEME + RC_ZGen_2Phase_inScheme;
278
0
  }
279
0
    else
280
0
  scheme = in->inScheme;
281
0
    if(scheme == TPM_ALG_NULL)
282
0
  return TPM_RCS_SCHEME + RC_ZGen_2Phase_inScheme;
283
    // Input points must be on the curve of keyA
284
0
    if(!CryptEccIsPointOnCurve(eccKey->publicArea.parameters.eccDetail.curveID,
285
0
             &in->inQsB.point))
286
0
  return TPM_RCS_ECC_POINT + RC_ZGen_2Phase_inQsB;
287
0
    if(!CryptEccIsPointOnCurve(eccKey->publicArea.parameters.eccDetail.curveID,
288
0
             &in->inQeB.point))
289
0
  return TPM_RCS_ECC_POINT + RC_ZGen_2Phase_inQeB;
290
0
    if(!CryptGenerateR(&r, &in->counter,
291
0
           eccKey->publicArea.parameters.eccDetail.curveID,
292
0
           NULL))
293
0
  return TPM_RCS_VALUE + RC_ZGen_2Phase_counter;
294
    // Command Output
295
0
    result = CryptEcc2PhaseKeyExchange(&out->outZ1.point,
296
0
               &out->outZ2.point,
297
0
               eccKey->publicArea.parameters.eccDetail.curveID,
298
0
               scheme,
299
0
               &eccKey->sensitive.sensitive.ecc,
300
0
               &r,
301
0
               &in->inQsB.point,
302
0
               &in->inQeB.point);
303
0
    if(result == TPM_RC_SCHEME)
304
0
  return TPM_RCS_SCHEME + RC_ZGen_2Phase_inScheme;
305
0
    if(result == TPM_RC_SUCCESS)
306
0
  CryptEndCommit(in->counter);
307
0
    return result;
308
0
}
309
#endif