xref: /aosp_15_r20/external/ms-tpm-20-ref/TPMCmd/tpm/src/crypt/CryptDes.c (revision 5c591343844d1f9da7da26467c4bf7efc8a7a413)
1*5c591343SA. Cody Schuffelen /* Microsoft Reference Implementation for TPM 2.0
2*5c591343SA. Cody Schuffelen  *
3*5c591343SA. Cody Schuffelen  *  The copyright in this software is being made available under the BSD License,
4*5c591343SA. Cody Schuffelen  *  included below. This software may be subject to other third party and
5*5c591343SA. Cody Schuffelen  *  contributor rights, including patent rights, and no such rights are granted
6*5c591343SA. Cody Schuffelen  *  under this license.
7*5c591343SA. Cody Schuffelen  *
8*5c591343SA. Cody Schuffelen  *  Copyright (c) Microsoft Corporation
9*5c591343SA. Cody Schuffelen  *
10*5c591343SA. Cody Schuffelen  *  All rights reserved.
11*5c591343SA. Cody Schuffelen  *
12*5c591343SA. Cody Schuffelen  *  BSD License
13*5c591343SA. Cody Schuffelen  *
14*5c591343SA. Cody Schuffelen  *  Redistribution and use in source and binary forms, with or without modification,
15*5c591343SA. Cody Schuffelen  *  are permitted provided that the following conditions are met:
16*5c591343SA. Cody Schuffelen  *
17*5c591343SA. Cody Schuffelen  *  Redistributions of source code must retain the above copyright notice, this list
18*5c591343SA. Cody Schuffelen  *  of conditions and the following disclaimer.
19*5c591343SA. Cody Schuffelen  *
20*5c591343SA. Cody Schuffelen  *  Redistributions in binary form must reproduce the above copyright notice, this
21*5c591343SA. Cody Schuffelen  *  list of conditions and the following disclaimer in the documentation and/or
22*5c591343SA. Cody Schuffelen  *  other materials provided with the distribution.
23*5c591343SA. Cody Schuffelen  *
24*5c591343SA. Cody Schuffelen  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25*5c591343SA. Cody Schuffelen  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*5c591343SA. Cody Schuffelen  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27*5c591343SA. Cody Schuffelen  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28*5c591343SA. Cody Schuffelen  *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29*5c591343SA. Cody Schuffelen  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30*5c591343SA. Cody Schuffelen  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31*5c591343SA. Cody Schuffelen  *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32*5c591343SA. Cody Schuffelen  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33*5c591343SA. Cody Schuffelen  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*5c591343SA. Cody Schuffelen  */
35*5c591343SA. Cody Schuffelen //** Introduction
36*5c591343SA. Cody Schuffelen //
37*5c591343SA. Cody Schuffelen // This file contains the extra functions required for TDES.
38*5c591343SA. Cody Schuffelen 
39*5c591343SA. Cody Schuffelen //** Includes, Defines, and Typedefs
40*5c591343SA. Cody Schuffelen #include "Tpm.h"
41*5c591343SA. Cody Schuffelen 
42*5c591343SA. Cody Schuffelen #if ALG_TDES
43*5c591343SA. Cody Schuffelen 
44*5c591343SA. Cody Schuffelen 
45*5c591343SA. Cody Schuffelen #define DES_NUM_WEAK 64
46*5c591343SA. Cody Schuffelen const UINT64 DesWeakKeys[DES_NUM_WEAK] = {
47*5c591343SA. Cody Schuffelen     0x0101010101010101ULL, 0xFEFEFEFEFEFEFEFEULL,
48*5c591343SA. Cody Schuffelen     0xE0E0E0E0F1F1F1F1ULL, 0x1F1F1F1F0E0E0E0EULL,
49*5c591343SA. Cody Schuffelen     0x011F011F010E010EULL, 0x1F011F010E010E01ULL,
50*5c591343SA. Cody Schuffelen     0x01E001E001F101F1ULL, 0xE001E001F101F101ULL,
51*5c591343SA. Cody Schuffelen     0x01FE01FE01FE01FEULL, 0xFE01FE01FE01FE01ULL,
52*5c591343SA. Cody Schuffelen     0x1FE01FE00EF10EF1ULL, 0xE01FE01FF10EF10EULL,
53*5c591343SA. Cody Schuffelen     0x1FFE1FFE0EFE0EFEULL, 0xFE1FFE1FFE0EFE0EULL,
54*5c591343SA. Cody Schuffelen     0xE0FEE0FEF1FEF1FEULL, 0xFEE0FEE0FEF1FEF1ULL,
55*5c591343SA. Cody Schuffelen     0x01011F1F01010E0EULL, 0x1F1F01010E0E0101ULL,
56*5c591343SA. Cody Schuffelen     0xE0E01F1FF1F10E0EULL, 0x0101E0E00101F1F1ULL,
57*5c591343SA. Cody Schuffelen     0x1F1FE0E00E0EF1F1ULL, 0xE0E0FEFEF1F1FEFEULL,
58*5c591343SA. Cody Schuffelen     0x0101FEFE0101FEFEULL, 0x1F1FFEFE0E0EFEFEULL,
59*5c591343SA. Cody Schuffelen     0xE0FE011FF1FE010EULL, 0x011F1F01010E0E01ULL,
60*5c591343SA. Cody Schuffelen     0x1FE001FE0EF101FEULL, 0xE0FE1F01F1FE0E01ULL,
61*5c591343SA. Cody Schuffelen     0x011FE0FE010EF1FEULL, 0x1FE0E01F0EF1F10EULL,
62*5c591343SA. Cody Schuffelen     0xE0FEFEE0F1FEFEF1ULL, 0x011FFEE0010EFEF1ULL,
63*5c591343SA. Cody Schuffelen     0x1FE0FE010EF1FE01ULL, 0xFE0101FEFE0101FEULL,
64*5c591343SA. Cody Schuffelen     0x01E01FFE01F10EFEULL, 0x1FFE01E00EFE01F1ULL,
65*5c591343SA. Cody Schuffelen     0xFE011FE0FE010EF1ULL, 0xFE01E01FFE01F10EULL,
66*5c591343SA. Cody Schuffelen     0x1FFEE0010EFEF101ULL, 0xFE1F01E0FE0E01F1ULL,
67*5c591343SA. Cody Schuffelen     0x01E0E00101F1F101ULL, 0x1FFEFE1F0EFEFE0EULL,
68*5c591343SA. Cody Schuffelen     0xFE1FE001FE0EF101ULL, 0x01E0FE1F01F1FE0EULL,
69*5c591343SA. Cody Schuffelen     0xE00101E0F10101F1ULL, 0xFE1F1FFEFE0E0EFEULL,
70*5c591343SA. Cody Schuffelen     0x01FE1FE001FE0EF1ULL, 0xE0011FFEF1010EFEULL,
71*5c591343SA. Cody Schuffelen     0xFEE0011FFEF1010EULL, 0x01FEE01F01FEF10EULL,
72*5c591343SA. Cody Schuffelen     0xE001FE1FF101FE0EULL, 0xFEE01F01FEF10E01ULL,
73*5c591343SA. Cody Schuffelen     0x01FEFE0101FEFE01ULL, 0xE01F01FEF10E01FEULL,
74*5c591343SA. Cody Schuffelen     0xFEE0E0FEFEF1F1FEULL, 0x1F01011F0E01010EULL,
75*5c591343SA. Cody Schuffelen     0xE01F1FE0F10E0EF1ULL, 0xFEFE0101FEFE0101ULL,
76*5c591343SA. Cody Schuffelen     0x1F01E0FE0E01F1FEULL, 0xE01FFE01F10EFE01ULL,
77*5c591343SA. Cody Schuffelen     0xFEFE1F1FFEFE0E0EULL, 0x1F01FEE00E01FEF1ULL,
78*5c591343SA. Cody Schuffelen     0xE0E00101F1F10101ULL, 0xFEFEE0E0FEFEF1F1ULL};
79*5c591343SA. Cody Schuffelen 
80*5c591343SA. Cody Schuffelen 
81*5c591343SA. Cody Schuffelen //*** CryptSetOddByteParity()
82*5c591343SA. Cody Schuffelen // This function sets the per byte parity of a 64-bit value. The least-significant
83*5c591343SA. Cody Schuffelen // bit is of each byte is replaced with the odd parity of the other 7 bits in the
84*5c591343SA. Cody Schuffelen // byte. With odd parity, no byte will ever be 0x00.
85*5c591343SA. Cody Schuffelen UINT64
CryptSetOddByteParity(UINT64 k)86*5c591343SA. Cody Schuffelen CryptSetOddByteParity(
87*5c591343SA. Cody Schuffelen     UINT64          k
88*5c591343SA. Cody Schuffelen     )
89*5c591343SA. Cody Schuffelen {
90*5c591343SA. Cody Schuffelen #define PMASK 0x0101010101010101ULL
91*5c591343SA. Cody Schuffelen     UINT64          out;
92*5c591343SA. Cody Schuffelen     k |= PMASK;     // set the parity bit
93*5c591343SA. Cody Schuffelen     out = k;
94*5c591343SA. Cody Schuffelen     k ^= k >> 4;
95*5c591343SA. Cody Schuffelen     k ^= k >> 2;
96*5c591343SA. Cody Schuffelen     k ^= k >> 1;
97*5c591343SA. Cody Schuffelen     k &= PMASK;     // odd parity extracted
98*5c591343SA. Cody Schuffelen     out ^= k;       // out is now even parity because parity bit was already set
99*5c591343SA. Cody Schuffelen     out ^= PMASK;   // out is now even parity
100*5c591343SA. Cody Schuffelen     return out;
101*5c591343SA. Cody Schuffelen }
102*5c591343SA. Cody Schuffelen 
103*5c591343SA. Cody Schuffelen 
104*5c591343SA. Cody Schuffelen //*** CryptDesIsWeakKey()
105*5c591343SA. Cody Schuffelen // Check to see if a DES key is on the list of weak, semi-weak, or possibly weak
106*5c591343SA. Cody Schuffelen // keys.
107*5c591343SA. Cody Schuffelen //  Return Type: BOOL
108*5c591343SA. Cody Schuffelen //      TRUE(1)         DES key is weak
109*5c591343SA. Cody Schuffelen //      FALSE(0)        DES key is not weak
110*5c591343SA. Cody Schuffelen static BOOL
CryptDesIsWeakKey(UINT64 k)111*5c591343SA. Cody Schuffelen CryptDesIsWeakKey(
112*5c591343SA. Cody Schuffelen     UINT64            k
113*5c591343SA. Cody Schuffelen     )
114*5c591343SA. Cody Schuffelen {
115*5c591343SA. Cody Schuffelen     int              i;
116*5c591343SA. Cody Schuffelen //
117*5c591343SA. Cody Schuffelen     for(i = 0; i < DES_NUM_WEAK; i++)
118*5c591343SA. Cody Schuffelen     {
119*5c591343SA. Cody Schuffelen         if(k == DesWeakKeys[i])
120*5c591343SA. Cody Schuffelen             return TRUE;
121*5c591343SA. Cody Schuffelen     }
122*5c591343SA. Cody Schuffelen     return FALSE;
123*5c591343SA. Cody Schuffelen }
124*5c591343SA. Cody Schuffelen 
125*5c591343SA. Cody Schuffelen //*** CryptDesValidateKey()
126*5c591343SA. Cody Schuffelen // Function to check to see if the input key is a valid DES key where the definition
127*5c591343SA. Cody Schuffelen // of valid is that none of the elements are on the list of weak, semi-weak, or
128*5c591343SA. Cody Schuffelen // possibly weak keys; and that for two keys, K1!=K2, and for three keys that
129*5c591343SA. Cody Schuffelen // K1!=K2 and K2!=K3.
130*5c591343SA. Cody Schuffelen BOOL
CryptDesValidateKey(TPM2B_SYM_KEY * desKey)131*5c591343SA. Cody Schuffelen CryptDesValidateKey(
132*5c591343SA. Cody Schuffelen     TPM2B_SYM_KEY       *desKey     // IN: key to validate
133*5c591343SA. Cody Schuffelen     )
134*5c591343SA. Cody Schuffelen {
135*5c591343SA. Cody Schuffelen     UINT64               k[3];
136*5c591343SA. Cody Schuffelen     int                  i;
137*5c591343SA. Cody Schuffelen     int                  keys = (desKey->t.size + 7) / 8;
138*5c591343SA. Cody Schuffelen     BYTE                *pk = desKey->t.buffer;
139*5c591343SA. Cody Schuffelen     BOOL                 ok;
140*5c591343SA. Cody Schuffelen //
141*5c591343SA. Cody Schuffelen     // Note: 'keys' is the number of keys, not the maximum index for 'k'
142*5c591343SA. Cody Schuffelen     ok = ((keys == 2) || (keys == 3)) && ((desKey->t.size % 8) == 0);
143*5c591343SA. Cody Schuffelen     for(i = 0; ok && i < keys; pk += 8, i++)
144*5c591343SA. Cody Schuffelen     {
145*5c591343SA. Cody Schuffelen         k[i] = CryptSetOddByteParity(BYTE_ARRAY_TO_UINT64(pk));
146*5c591343SA. Cody Schuffelen         ok = !CryptDesIsWeakKey(k[i]);
147*5c591343SA. Cody Schuffelen     }
148*5c591343SA. Cody Schuffelen     ok = ok && k[0] != k[1];
149*5c591343SA. Cody Schuffelen     if(keys == 3)
150*5c591343SA. Cody Schuffelen         ok = ok && k[1] != k[2];
151*5c591343SA. Cody Schuffelen     return ok;
152*5c591343SA. Cody Schuffelen }
153*5c591343SA. Cody Schuffelen 
154*5c591343SA. Cody Schuffelen //*** CryptGenerateKeyDes()
155*5c591343SA. Cody Schuffelen // This function is used to create a DES key of the appropriate size. The key will
156*5c591343SA. Cody Schuffelen // have odd parity in the bytes.
157*5c591343SA. Cody Schuffelen TPM_RC
CryptGenerateKeyDes(TPMT_PUBLIC * publicArea,TPMT_SENSITIVE * sensitive,RAND_STATE * rand)158*5c591343SA. Cody Schuffelen CryptGenerateKeyDes(
159*5c591343SA. Cody Schuffelen     TPMT_PUBLIC             *publicArea,        // IN/OUT: The public area template
160*5c591343SA. Cody Schuffelen                                                 //     for the new key.
161*5c591343SA. Cody Schuffelen     TPMT_SENSITIVE          *sensitive,         // OUT: sensitive area
162*5c591343SA. Cody Schuffelen     RAND_STATE              *rand               // IN: the "entropy" source for
163*5c591343SA. Cody Schuffelen     )
164*5c591343SA. Cody Schuffelen {
165*5c591343SA. Cody Schuffelen 
166*5c591343SA. Cody Schuffelen     // Assume that the publicArea key size has been validated and is a supported
167*5c591343SA. Cody Schuffelen     // number of bits.
168*5c591343SA. Cody Schuffelen     sensitive->sensitive.sym.t.size =
169*5c591343SA. Cody Schuffelen             BITS_TO_BYTES(publicArea->parameters.symDetail.sym.keyBits.sym);
170*5c591343SA. Cody Schuffelen     do
171*5c591343SA. Cody Schuffelen     {
172*5c591343SA. Cody Schuffelen         BYTE                    *pK = sensitive->sensitive.sym.t.buffer;
173*5c591343SA. Cody Schuffelen         int                      i = (sensitive->sensitive.sym.t.size + 7) / 8;
174*5c591343SA. Cody Schuffelen // Use the random number generator to generate the required number of bits
175*5c591343SA. Cody Schuffelen         if(DRBG_Generate(rand, pK, sensitive->sensitive.sym.t.size) == 0)
176*5c591343SA. Cody Schuffelen             return TPM_RC_NO_RESULT;
177*5c591343SA. Cody Schuffelen         for(; i > 0; pK += 8, i--)
178*5c591343SA. Cody Schuffelen         {
179*5c591343SA. Cody Schuffelen             UINT64      k = BYTE_ARRAY_TO_UINT64(pK);
180*5c591343SA. Cody Schuffelen             k = CryptSetOddByteParity(k);
181*5c591343SA. Cody Schuffelen             UINT64_TO_BYTE_ARRAY(k, pK);
182*5c591343SA. Cody Schuffelen         }
183*5c591343SA. Cody Schuffelen     } while(!CryptDesValidateKey(&sensitive->sensitive.sym));
184*5c591343SA. Cody Schuffelen     return TPM_RC_SUCCESS;
185*5c591343SA. Cody Schuffelen }
186*5c591343SA. Cody Schuffelen 
187*5c591343SA. Cody Schuffelen #endif
188*5c591343SA. Cody Schuffelen //***
189