Coverage Report

Created: 2026-02-11 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libtpms/src/tpm2/crypto/openssl/CryptDes.c
Line
Count
Source
1
/********************************************************************************/
2
/*                    */
3
/*         Functions Required for TDES        */
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
/* 10.2.9 CryptDes.c */
62
/* 10.2.9.1 Introduction */
63
/* This file contains the extra functions required for TDES. */
64
/* 10.2.9.2 Includes, Defines, and Typedefs */
65
#include "Tpm.h"
66
#include "Helpers_fp.h"                // libtpms added
67
#if ALG_TDES
68
19.5k
#define DES_NUM_WEAK 64
69
const UINT64 DesWeakKeys[DES_NUM_WEAK] = {
70
    0x0101010101010101ULL, 0xFEFEFEFEFEFEFEFEULL, 0xE0E0E0E0F1F1F1F1ULL, 0x1F1F1F1F0E0E0E0EULL,
71
    0x011F011F010E010EULL, 0x1F011F010E010E01ULL, 0x01E001E001F101F1ULL, 0xE001E001F101F101ULL,
72
    0x01FE01FE01FE01FEULL, 0xFE01FE01FE01FE01ULL, 0x1FE01FE00EF10EF1ULL, 0xE01FE01FF10EF10EULL,
73
    0x1FFE1FFE0EFE0EFEULL, 0xFE1FFE1FFE0EFE0EULL, 0xE0FEE0FEF1FEF1FEULL, 0xFEE0FEE0FEF1FEF1ULL,
74
    0x01011F1F01010E0EULL, 0x1F1F01010E0E0101ULL, 0xE0E01F1FF1F10E0EULL, 0x0101E0E00101F1F1ULL,
75
    0x1F1FE0E00E0EF1F1ULL, 0xE0E0FEFEF1F1FEFEULL, 0x0101FEFE0101FEFEULL, 0x1F1FFEFE0E0EFEFEULL,
76
    0xE0FE011FF1FE010EULL, 0x011F1F01010E0E01ULL, 0x1FE001FE0EF101FEULL, 0xE0FE1F01F1FE0E01ULL,
77
    0x011FE0FE010EF1FEULL, 0x1FE0E01F0EF1F10EULL, 0xE0FEFEE0F1FEFEF1ULL, 0x011FFEE0010EFEF1ULL,
78
    0x1FE0FE010EF1FE01ULL, 0xFE0101FEFE0101FEULL, 0x01E01FFE01F10EFEULL, 0x1FFE01E00EFE01F1ULL,
79
    0xFE011FE0FE010EF1ULL, 0xFE01E01FFE01F10EULL, 0x1FFEE0010EFEF101ULL, 0xFE1F01E0FE0E01F1ULL,
80
    0x01E0E00101F1F101ULL, 0x1FFEFE1F0EFEFE0EULL, 0xFE1FE001FE0EF101ULL, 0x01E0FE1F01F1FE0EULL,
81
    0xE00101E0F10101F1ULL, 0xFE1F1FFEFE0E0EFEULL, 0x01FE1FE001FE0EF1ULL, 0xE0011FFEF1010EFEULL,
82
    0xFEE0011FFEF1010EULL, 0x01FEE01F01FEF10EULL, 0xE001FE1FF101FE0EULL, 0xFEE01F01FEF10E01ULL,
83
    0x01FEFE0101FEFE01ULL, 0xE01F01FEF10E01FEULL, 0xFEE0E0FEFEF1F1FEULL, 0x1F01011F0E01010EULL,
84
    0xE01F1FE0F10E0EF1ULL, 0xFEFE0101FEFE0101ULL, 0x1F01E0FE0E01F1FEULL, 0xE01FFE01F10EFE01ULL,
85
    0xFEFE1F1FFEFE0E0EULL, 0x1F01FEE00E01FEF1ULL, 0xE0E00101F1F10101ULL, 0xFEFEE0E0FEFEF1F1ULL};
86
/* 10.2.9.2.1 CryptSetOddByteParity() */
87
/* This function sets the per byte parity of a 64-bit value. The least-significant bit is of each
88
   byte is replaced with the odd parity of the other 7 bits in the byte. With odd parity, no byte
89
   will ever be 0x00. */
90
UINT64
91
CryptSetOddByteParity(
92
          UINT64          k
93
          )
94
383
{
95
1.14k
#define PMASK 0x0101010101010101ULL
96
383
    UINT64          out;
97
383
    k |= PMASK;     // set the parity bit
98
383
    out = k;
99
383
    k ^= k >> 4;
100
383
    k ^= k >> 2;
101
383
    k ^= k >> 1;
102
383
    k &= PMASK;     // odd parity extracted
103
383
    out ^= k;       // out is now even parity because parity bit was already set
104
383
    out ^= PMASK;   // out is now even parity
105
383
    return out;
106
383
}
107
/* 10.2.9.2.2 CryptDesIsWeakKey() */
108
/* Check to see if a DES key is on the list of weak, semi-weak, or possibly weak keys. */
109
/* Return Value Meaning */
110
/* TRUE(1)  DES key is weak */
111
/* FALSE(0) DES key is not weak */
112
static BOOL
113
CryptDesIsWeakKey(
114
      UINT64            k
115
      )
116
306
{
117
306
    int              i;
118
    //
119
19.5k
    for(i = 0; i < DES_NUM_WEAK; i++)
120
19.2k
  {
121
19.2k
      if(k == DesWeakKeys[i])
122
5
    return TRUE;
123
19.2k
  }
124
301
    return FALSE;
125
306
}
126
/* 10.2.9.2.3 CryptDesValidateKey() */
127
/* Function to check to see if the input key is a valid DES key where the definition of valid is
128
   that none of the elements are on the list of weak, semi-weak, or possibly weak keys; and that for
129
   two keys, K1!=K2, and for three keys that K1!=K2 and K2!=K3. */
130
BOOL
131
CryptDesValidateKey(
132
        TPM2B_SYM_KEY       *desKey     // IN: key to validate
133
        )
134
106
{
135
106
    UINT64               k[3];
136
106
    int                  i;
137
106
    int                  keys = (desKey->t.size + 7) / 8;
138
106
    BYTE                *pk = desKey->t.buffer;
139
106
    BOOL                 ok;
140
    //
141
    // Note: 'keys' is the number of keys, not the maximum index for 'k'
142
106
    ok = ((keys == 2) || (keys == 3)) && ((desKey->t.size % 8) == 0);
143
412
    for(i = 0; ok && i < keys; pk += 8, i++)
144
306
  {
145
306
      k[i] = CryptSetOddByteParity(BYTE_ARRAY_TO_UINT64(pk));
146
306
      ok = !CryptDesIsWeakKey(k[i]);
147
306
  }
148
106
    ok = ok && k[0] != k[1];
149
106
    if(keys == 3)
150
101
  ok = ok && k[1] != k[2];
151
106
    return ok;
152
106
}
153
/* 10.2.9.2.4 CryptGenerateKeyDes() */
154
/* This function is used to create a DES key of the appropriate size. The key will have odd parity
155
   in the bytes. */
156
TPM_RC
157
CryptGenerateKeyDes(
158
        TPMT_PUBLIC             *publicArea,        // IN/OUT: The public area template
159
        //     for the new key.
160
        TPMT_SENSITIVE          *sensitive,         // OUT: sensitive area
161
        RAND_STATE              *rand               // IN: the "entropy" source for
162
        )
163
27
{
164
    // Assume that the publicArea key size has been validated and is a supported
165
    // number of bits.
166
27
    sensitive->sensitive.sym.t.size =
167
27
  BITS_TO_BYTES(publicArea->parameters.symDetail.sym.keyBits.sym);
168
    // Because we use BYTE_ARRAY_TO_UINT64 below, require the requested DES key
169
    // to be a multiple of 8 bytes in size.
170
27
    if((sensitive->sensitive.sym.t.size % 8) != 0)
171
0
  {
172
0
      return TPM_RC_SYMMETRIC;
173
0
  }
174
#if USE_OPENSSL_FUNCTIONS_SYMMETRIC    // libtpms added begin
175
27
    if (rand == NULL)
176
0
        return OpenSSLCryptGenerateKeyDes(sensitive);
177
27
#endif                                 // libtpms added end
178
27
    do
179
27
  {
180
27
      BYTE                    *pK = sensitive->sensitive.sym.t.buffer;
181
27
      int                      i = (sensitive->sensitive.sym.t.size + 7) / 8;
182
      // Use the random number generator to generate the required number of bits
183
27
      if(DRBG_Generate(rand, pK, sensitive->sensitive.sym.t.size) == 0)
184
0
    return TPM_RC_NO_RESULT;
185
104
      for(; i > 0; pK += 8, i--)
186
77
    {
187
77
        UINT64      k = BYTE_ARRAY_TO_UINT64(pK);
188
77
        k = CryptSetOddByteParity(k);
189
77
        UINT64_TO_BYTE_ARRAY(k, pK);
190
77
    }
191
27
  } while(!CryptDesValidateKey(&sensitive->sensitive.sym));
192
27
    return TPM_RC_SUCCESS;
193
27
}
194
#endif