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