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