• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stefanberger / libtpms / #2022

23 Sep 2025 01:11PM UTC coverage: 77.227% (+0.009%) from 77.218%
#2022

push

travis-ci

web-flow
Merge a45c293de into 4504f47c6

36116 of 46766 relevant lines covered (77.23%)

125180.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.0
/src/tpm2/EncryptDecrypt_spt.c
1
/********************************************************************************/
2
/*                                                                                */
3
/*                                 Encrypt Decrypt Support                         */
4
/*                             Written by Ken Goldman                                */
5
/*                       IBM Thomas J. Watson Research Center                        */
6
/*            $Id: EncryptDecrypt_spt.c 1658 2021-01-22 23:14:01Z 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 - 2021                                */
59
/*                                                                                */
60
/********************************************************************************/
61

62
#include "Tpm.h"
63
#include "EncryptDecrypt_fp.h"
64
#include "EncryptDecrypt_spt_fp.h"
65

66
#if CC_EncryptDecrypt2
67

68
/*(See part 3 specification)
69
// symmetric encryption or decryption
70
*/
71
//  Return Type: TPM_RC
72
//      TPM_RC_KEY          is not a symmetric decryption key with both
73
//                          public and private portions loaded
74
//      TPM_RC_SIZE         'IvIn' size is incompatible with the block cipher mode;
75
//                          or 'inData' size is not an even multiple of the block
76
//                          size for CBC or ECB mode
77
//      TPM_RC_VALUE        'keyHandle' is restricted and the argument 'mode' does
78
//                          not match the key's mode
79
TPM_RC
80
EncryptDecryptShared(TPMI_DH_OBJECT      keyHandleIn,
24✔
81
                     TPMI_YES_NO         decryptIn,
82
                     TPMI_ALG_SYM_MODE   modeIn,
83
                     TPM2B_IV*           ivIn,
84
                     TPM2B_MAX_BUFFER*   inData,
85
                     EncryptDecrypt_Out* out)
86
{
87
    OBJECT*    symKey;
24✔
88
    UINT16     keySize;
24✔
89
    UINT16     blockSize;
24✔
90
    BYTE*      key;
24✔
91
    TPM_ALG_ID alg;
24✔
92
    TPM_ALG_ID mode;
24✔
93
    TPM_RC     result;
24✔
94
    BOOL       OK;
24✔
95
    // Input Validation
96
    symKey = HandleToObject(keyHandleIn);
24✔
97
    mode   = symKey->publicArea.parameters.symDetail.sym.mode.sym;
24✔
98

99
    // The input key should be a symmetric key
100
    if(symKey->publicArea.type != TPM_ALG_SYMCIPHER)
24✔
101
        return TPM_RCS_KEY + RC_EncryptDecrypt_keyHandle;
102
    // The key must be unrestricted and allow the selected operation
103
    OK = !IS_ATTRIBUTE(symKey->publicArea.objectAttributes, TPMA_OBJECT, restricted);
24✔
104
    if(YES == decryptIn)
24✔
105
        OK = OK
12✔
106
             && IS_ATTRIBUTE(
12✔
107
                 symKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt);
108
    else
109
        OK = OK
12✔
110
             && IS_ATTRIBUTE(symKey->publicArea.objectAttributes, TPMA_OBJECT, sign);
12✔
111
    if(!OK)
112
        return TPM_RCS_ATTRIBUTES + RC_EncryptDecrypt_keyHandle;
113

114
    // Make sure that key is an encrypt/decrypt key and not SMAC
115
    if(!CryptSymModeIsValid(mode, TRUE))
24✔
116
        return TPM_RCS_MODE + RC_EncryptDecrypt_keyHandle;
117

118
    // If the key mode is not TPM_ALG_NULL...
119
    // or TPM_ALG_NULL
120
    if(mode != TPM_ALG_NULL)
24✔
121
    {
122
        // then the input mode has to be TPM_ALG_NULL or the same as the key
123
        if((modeIn != TPM_ALG_NULL) && (modeIn != mode))
24✔
124
            return TPM_RCS_MODE + RC_EncryptDecrypt_mode;
125
    }
126
    else
127
    {
128
        // if the key mode is null, then the input can't be null
129
        if(modeIn == TPM_ALG_NULL)
×
130
            return TPM_RCS_MODE + RC_EncryptDecrypt_mode;
131
        mode = modeIn;
132
    }
133
    // The input iv for ECB mode should be an Empty Buffer.  All the other modes
134
    // should have an iv size same as encryption block size
135
    keySize   = symKey->publicArea.parameters.symDetail.sym.keyBits.sym;
24✔
136
    alg       = symKey->publicArea.parameters.symDetail.sym.algorithm;
24✔
137
    blockSize = CryptGetSymmetricBlockSize(alg, keySize);
24✔
138

139
    // reverify the algorithm. This is mainly to keep static analysis tools happy
140
    if(blockSize == 0)
24✔
141
        return TPM_RCS_KEY + RC_EncryptDecrypt_keyHandle;
142

143
    if(((mode == TPM_ALG_ECB) && (ivIn->t.size != 0))
24✔
144
       || ((mode != TPM_ALG_ECB) && (ivIn->t.size != blockSize)))
24✔
145
        return TPM_RCS_SIZE + RC_EncryptDecrypt_ivIn;
146

147
    // The input data size of CBC mode or ECB mode must be an even multiple of
148
    // the symmetric algorithm's block size
149
    if(((mode == TPM_ALG_CBC) || (mode == TPM_ALG_ECB))
24✔
150
       && ((inData->t.size % blockSize) != 0))
×
151
        return TPM_RCS_SIZE + RC_EncryptDecrypt_inData;
152

153
    // Copy IV
154
    // Note: This is copied here so that the calls to the encrypt/decrypt functions
155
    // will modify the output buffer, not the input buffer
156
    out->ivOut = *ivIn;
24✔
157

158
    // Command Output
159
    key = symKey->sensitive.sensitive.sym.t.buffer;
24✔
160
    // For symmetric encryption, the cipher data size is the same as plain data
161
    // size.
162
    out->outData.t.size = inData->t.size;
24✔
163
    if(decryptIn == YES)
24✔
164
    {
165
        // Decrypt data to output
166
        result = CryptSymmetricDecrypt(out->outData.t.buffer,
12✔
167
                                       alg,
168
                                       keySize,
169
                                       key,
170
                                       &(out->ivOut),
171
                                       mode,
172
                                       inData->t.size,
12✔
173
                                       inData->t.buffer);
12✔
174
    }
175
    else
176
    {
177
        // Encrypt data to output
178
        result = CryptSymmetricEncrypt(out->outData.t.buffer,
12✔
179
                                       alg,
180
                                       keySize,
181
                                       key,
182
                                       &(out->ivOut),
183
                                       mode,
184
                                       inData->t.size,
12✔
185
                                       inData->t.buffer);
12✔
186
    }
187
    return result;
188
}
189

190
#endif  // CC_EncryptDecrypt
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc