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