/src/ibmswtpm2/src/CryptSym.c
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************************/ |
2 | | /* */ |
3 | | /* Symmetric block cipher modes */ |
4 | | /* Written by Ken Goldman */ |
5 | | /* IBM Thomas J. Watson Research Center */ |
6 | | /* $Id: CryptSym.c 1311 2018-08-23 21:39:29Z kgoldman $ */ |
7 | | /* */ |
8 | | /* Licenses and Notices */ |
9 | | /* */ |
10 | | /* 1. Copyright Licenses: */ |
11 | | /* */ |
12 | | /* - Trusted Computing Group (TCG) grants to the user of the source code in */ |
13 | | /* this specification (the "Source Code") a worldwide, irrevocable, */ |
14 | | /* nonexclusive, royalty free, copyright license to reproduce, create */ |
15 | | /* derivative works, distribute, display and perform the Source Code and */ |
16 | | /* derivative works thereof, and to grant others the rights granted herein. */ |
17 | | /* */ |
18 | | /* - The TCG grants to the user of the other parts of the specification */ |
19 | | /* (other than the Source Code) the rights to reproduce, distribute, */ |
20 | | /* display, and perform the specification solely for the purpose of */ |
21 | | /* developing products based on such documents. */ |
22 | | /* */ |
23 | | /* 2. Source Code Distribution Conditions: */ |
24 | | /* */ |
25 | | /* - Redistributions of Source Code must retain the above copyright licenses, */ |
26 | | /* this list of conditions and the following disclaimers. */ |
27 | | /* */ |
28 | | /* - Redistributions in binary form must reproduce the above copyright */ |
29 | | /* licenses, this list of conditions and the following disclaimers in the */ |
30 | | /* documentation and/or other materials provided with the distribution. */ |
31 | | /* */ |
32 | | /* 3. Disclaimers: */ |
33 | | /* */ |
34 | | /* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ |
35 | | /* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ |
36 | | /* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ |
37 | | /* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ |
38 | | /* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ |
39 | | /* information on specification licensing rights available through TCG */ |
40 | | /* membership agreements. */ |
41 | | /* */ |
42 | | /* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ |
43 | | /* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ |
44 | | /* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ |
45 | | /* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ |
46 | | /* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ |
47 | | /* */ |
48 | | /* - Without limitation, TCG and its members and licensors disclaim all */ |
49 | | /* liability, including liability for infringement of any proprietary */ |
50 | | /* rights, relating to use of information in this specification and to the */ |
51 | | /* implementation of this specification, and TCG disclaims all liability for */ |
52 | | /* cost of procurement of substitute goods or services, lost profits, loss */ |
53 | | /* of use, loss of data or any incidental, consequential, direct, indirect, */ |
54 | | /* or special damages, whether under contract, tort, warranty or otherwise, */ |
55 | | /* arising in any way out of use or reliance upon this specification or any */ |
56 | | /* information herein. */ |
57 | | /* */ |
58 | | /* (c) Copyright IBM Corp. and others, 2016 - 2018 */ |
59 | | /* */ |
60 | | /********************************************************************************/ |
61 | | |
62 | | /* 10.2.19 CryptSym.c */ |
63 | | /* 10.2.19.1 Introduction */ |
64 | | /* This file contains the implementation of the symmetric block cipher modes allowed for a |
65 | | TPM. These functions only use the single block encryption functions of the selected symmetric |
66 | | crypto library. */ |
67 | | /* 10.2.19.2 Includes, Defines, and Typedefs */ |
68 | | #include "Tpm.h" |
69 | | #include "CryptSym.h" |
70 | | /* 10.2.19.3.1 CryptSymInit() */ |
71 | | /* This function is called to do _TPM_Init() processing */ |
72 | | BOOL |
73 | | CryptSymInit( |
74 | | void |
75 | | ) |
76 | 657 | { |
77 | 657 | return TRUE; |
78 | 657 | } |
79 | | /* 10.2.19.3.2 CryptSymStartup() */ |
80 | | /* This function is called to do TPM2_Startup() processing */ |
81 | | BOOL |
82 | | CryptSymStartup( |
83 | | void |
84 | | ) |
85 | 656 | { |
86 | 656 | return TRUE; |
87 | 656 | } |
88 | | /* 10.2.20.4 Data Access Functions */ |
89 | | /* 10.2.20.4.1 CryptGetSymmetricBlockSize() */ |
90 | | /* This function returns the block size of the algorithm. */ |
91 | | /* Return Values Meaning */ |
92 | | /* <= 0 cipher not supported */ |
93 | | /* > 0 the cipher block size in bytes */ |
94 | | LIB_EXPORT INT16 |
95 | | CryptGetSymmetricBlockSize( |
96 | | TPM_ALG_ID symmetricAlg, // IN: the symmetric algorithm |
97 | | UINT16 keySizeInBits // IN: the key size |
98 | | ) |
99 | 0 | { |
100 | 0 | switch(symmetricAlg) |
101 | 0 | { |
102 | 0 | #if ALG_AES |
103 | 0 | case ALG_AES_VALUE: |
104 | 0 | switch(keySizeInBits) |
105 | 0 | { |
106 | 0 | case 128: |
107 | 0 | return AES_128_BLOCK_SIZE_BYTES; |
108 | 0 | case 192: |
109 | 0 | return AES_192_BLOCK_SIZE_BYTES; |
110 | 0 | case 256: |
111 | 0 | return AES_256_BLOCK_SIZE_BYTES; |
112 | 0 | default: |
113 | 0 | break; |
114 | 0 | } |
115 | 0 | break; |
116 | 0 | #endif |
117 | | #if ALG_SM4 |
118 | | case ALG_SM4_VALUE: |
119 | | switch(keySizeInBits) |
120 | | { |
121 | | case 128: |
122 | | return SM4_128_BLOCK_SIZE_BYTES; |
123 | | default: |
124 | | break; |
125 | | } |
126 | | #endif |
127 | | #if ALG_CAMELLIA |
128 | | case ALG_CAMELLIA_VALUE: |
129 | | switch(keySizeInBits) |
130 | | { |
131 | | case 128: |
132 | | return CAMELLIA_128_BLOCK_SIZE_BYTES; |
133 | | case 192: |
134 | | return CAMELLIA_192_BLOCK_SIZE_BYTES; |
135 | | case 256: |
136 | | return CAMELLIA_256_BLOCK_SIZE_BYTES; |
137 | | default: |
138 | | break; |
139 | | } |
140 | | #endif |
141 | | #if ALG_TDES |
142 | | case ALG_TDES_VALUE: |
143 | | switch(keySizeInBits) |
144 | | { |
145 | | case 128: |
146 | | return TDES_128_BLOCK_SIZE_BYTES; |
147 | | case 192: |
148 | | return TDES_192_BLOCK_SIZE_BYTES; |
149 | | default: |
150 | | break; |
151 | | } |
152 | | #endif |
153 | 0 | default: |
154 | 0 | break; |
155 | 0 | } |
156 | 0 | return 0; |
157 | 0 | } |
158 | | /* 10.2.20.5 Symmetric Encryption */ |
159 | | /* This function performs symmetric encryption based on the mode. */ |
160 | | /* Error Returns Meaning */ |
161 | | /* TPM_RC_SUCCESS if success */ |
162 | | /* TPM_RC_SIZE dSize is not a multiple of the block size for an algorithm that requires it */ |
163 | | /* TPM_RC_FAILURE Fatal error */ |
164 | | LIB_EXPORT TPM_RC |
165 | | CryptSymmetricEncrypt( |
166 | | BYTE *dOut, // OUT: |
167 | | TPM_ALG_ID algorithm, // IN: the symmetric algorithm |
168 | | UINT16 keySizeInBits, // IN: key size in bits |
169 | | const BYTE *key, // IN: key buffer. The size of this buffer |
170 | | // in bytes is (keySizeInBits + 7) / 8 |
171 | | TPM2B_IV *ivInOut, // IN/OUT: IV for decryption. |
172 | | TPM_ALG_ID mode, // IN: Mode to use |
173 | | INT32 dSize, // IN: data size (may need to be a |
174 | | // multiple of the blockSize) |
175 | | const BYTE *dIn // IN: data buffer |
176 | | ) |
177 | 0 | { |
178 | 0 | BYTE *pIv; |
179 | 0 | int i; |
180 | 0 | BYTE tmp[MAX_SYM_BLOCK_SIZE]; |
181 | 0 | BYTE *pT; |
182 | 0 | tpmCryptKeySchedule_t keySchedule; |
183 | 0 | INT16 blockSize; |
184 | 0 | TpmCryptSetSymKeyCall_t encrypt; |
185 | 0 | BYTE *iv; |
186 | 0 | BYTE defaultIv[MAX_SYM_BLOCK_SIZE] = {0}; |
187 | | // |
188 | 0 | pAssert(dOut != NULL && key != NULL && dIn != NULL); |
189 | 0 | if(dSize == 0) |
190 | 0 | return TPM_RC_SUCCESS; |
191 | 0 | TEST(algorithm); |
192 | 0 | blockSize = CryptGetSymmetricBlockSize(algorithm, keySizeInBits); |
193 | 0 | if(blockSize == 0) |
194 | 0 | return TPM_RC_FAILURE; |
195 | | // If the iv is provided, then it is expected to be block sized. In some cases, |
196 | | // the caller is providing an array of 0's that is equal to [MAX_SYM_BLOCK_SIZE] |
197 | | // with no knowledge of the actual block size. This function will set it. |
198 | 0 | if((ivInOut != NULL) && (mode != ALG_ECB_VALUE)) |
199 | 0 | { |
200 | 0 | ivInOut->t.size = blockSize; |
201 | 0 | iv = ivInOut->t.buffer; |
202 | 0 | } |
203 | 0 | else |
204 | 0 | iv = defaultIv; |
205 | 0 | pIv = iv; |
206 | | // Create encrypt key schedule and set the encryption function pointer. |
207 | 0 | SELECT(ENCRYPT); |
208 | 0 | switch(mode) |
209 | 0 | { |
210 | 0 | #if ALG_CTR |
211 | 0 | case ALG_CTR_VALUE: |
212 | 0 | for(; dSize > 0; dSize -= blockSize) |
213 | 0 | { |
214 | | // Encrypt the current value of the IV(counter) |
215 | 0 | ENCRYPT(&keySchedule, iv, tmp); |
216 | | //increment the counter (counter is big-endian so start at end) |
217 | 0 | for(i = blockSize - 1; i >= 0; i--) |
218 | 0 | if((iv[i] += 1) != 0) |
219 | 0 | break; |
220 | | // XOR the encrypted counter value with input and put into output |
221 | 0 | pT = tmp; |
222 | 0 | for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--) |
223 | 0 | *dOut++ = *dIn++ ^ *pT++; |
224 | 0 | } |
225 | 0 | break; |
226 | 0 | #endif |
227 | 0 | #if ALG_OFB |
228 | 0 | case ALG_OFB_VALUE: |
229 | | // This is written so that dIn and dOut may be the same |
230 | 0 | for(; dSize > 0; dSize -= blockSize) |
231 | 0 | { |
232 | | // Encrypt the current value of the "IV" |
233 | 0 | ENCRYPT(&keySchedule, iv, iv); |
234 | | // XOR the encrypted IV into dIn to create the cipher text (dOut) |
235 | 0 | pIv = iv; |
236 | 0 | for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--) |
237 | 0 | *dOut++ = (*pIv++ ^ *dIn++); |
238 | 0 | } |
239 | 0 | break; |
240 | 0 | #endif |
241 | 0 | #if ALG_CBC |
242 | 0 | case ALG_CBC_VALUE: |
243 | | // For CBC the data size must be an even multiple of the |
244 | | // cipher block size |
245 | 0 | if((dSize % blockSize) != 0) |
246 | 0 | return TPM_RC_SIZE; |
247 | | // XOR the data block into the IV, encrypt the IV into the IV |
248 | | // and then copy the IV to the output |
249 | 0 | for(; dSize > 0; dSize -= blockSize) |
250 | 0 | { |
251 | 0 | pIv = iv; |
252 | 0 | for(i = blockSize; i > 0; i--) |
253 | 0 | *pIv++ ^= *dIn++; |
254 | 0 | ENCRYPT(&keySchedule, iv, iv); |
255 | 0 | pIv = iv; |
256 | 0 | for(i = blockSize; i > 0; i--) |
257 | 0 | *dOut++ = *pIv++; |
258 | 0 | } |
259 | 0 | break; |
260 | 0 | #endif |
261 | | // CFB is not optional |
262 | 0 | case ALG_CFB_VALUE: |
263 | | // Encrypt the IV into the IV, XOR in the data, and copy to output |
264 | 0 | for(; dSize > 0; dSize -= blockSize) |
265 | 0 | { |
266 | | // Encrypt the current value of the IV |
267 | 0 | ENCRYPT(&keySchedule, iv, iv); |
268 | 0 | pIv = iv; |
269 | 0 | for(i = (int)(dSize < blockSize) ? dSize : blockSize; i > 0; i--) |
270 | | // XOR the data into the IV to create the cipher text |
271 | | // and put into the output |
272 | 0 | *dOut++ = *pIv++ ^= *dIn++; |
273 | 0 | } |
274 | | // If the inner loop (i loop) was smaller than blockSize, then dSize |
275 | | // would have been smaller than blockSize and it is now negative. If |
276 | | // it is negative, then it indicates how many bytes are needed to pad |
277 | | // out the IV for the next round. |
278 | 0 | for(; dSize < 0; dSize++) |
279 | 0 | *pIv++ = 0; |
280 | 0 | break; |
281 | 0 | #if ALG_ECB |
282 | 0 | case ALG_ECB_VALUE: |
283 | | // For ECB the data size must be an even multiple of the |
284 | | // cipher block size |
285 | 0 | if((dSize % blockSize) != 0) |
286 | 0 | return TPM_RC_SIZE; |
287 | | // Encrypt the input block to the output block |
288 | 0 | for(; dSize > 0; dSize -= blockSize) |
289 | 0 | { |
290 | 0 | ENCRYPT(&keySchedule, dIn, dOut); |
291 | 0 | dIn = &dIn[blockSize]; |
292 | 0 | dOut = &dOut[blockSize]; |
293 | 0 | } |
294 | 0 | break; |
295 | 0 | #endif |
296 | 0 | default: |
297 | 0 | return TPM_RC_FAILURE; |
298 | 0 | } |
299 | 0 | return TPM_RC_SUCCESS; |
300 | 0 | } |
301 | | /* 10.2.20.5.1 CryptSymmetricDecrypt() */ |
302 | | /* This function performs symmetric decryption based on the mode. */ |
303 | | /* Error Returns Meaning */ |
304 | | /* TPM_RC_FAILURE A fatal error */ |
305 | | /* TPM_RC_SUCCESS if success */ |
306 | | /* TPM_RCS_SIZE dSize is not a multiple of the block size for an algorithm that requires it */ |
307 | | LIB_EXPORT TPM_RC |
308 | | CryptSymmetricDecrypt( |
309 | | BYTE *dOut, // OUT: decrypted data |
310 | | TPM_ALG_ID algorithm, // IN: the symmetric algorithm |
311 | | UINT16 keySizeInBits, // IN: key size in bits |
312 | | const BYTE *key, // IN: key buffer. The size of this buffer |
313 | | // in bytes is (keySizeInBits + 7) / 8 |
314 | | TPM2B_IV *ivInOut, // IN/OUT: IV for decryption. |
315 | | TPM_ALG_ID mode, // IN: Mode to use |
316 | | INT32 dSize, // IN: data size (may need to be a |
317 | | // multiple of the blockSize) |
318 | | const BYTE *dIn // IN: data buffer |
319 | | ) |
320 | 0 | { |
321 | 0 | BYTE *pIv; |
322 | 0 | int i; |
323 | 0 | BYTE tmp[MAX_SYM_BLOCK_SIZE]; |
324 | 0 | BYTE *pT; |
325 | 0 | tpmCryptKeySchedule_t keySchedule; |
326 | 0 | INT16 blockSize; |
327 | 0 | BYTE *iv; |
328 | 0 | TpmCryptSetSymKeyCall_t encrypt; |
329 | 0 | TpmCryptSetSymKeyCall_t decrypt; |
330 | 0 | BYTE defaultIv[MAX_SYM_BLOCK_SIZE] = {0}; |
331 | | // These are used but the compiler can't tell because they are initialized |
332 | | // in case statements and it can't tell if they are always initialized |
333 | | // when needed, so... Comment these out if the compiler can tell or doesn't |
334 | | // care that these are initialized before use. |
335 | 0 | encrypt = NULL; |
336 | 0 | decrypt = NULL; |
337 | 0 | pAssert(dOut != NULL && key != NULL && dIn != NULL); |
338 | 0 | if(dSize == 0) |
339 | 0 | return TPM_RC_SUCCESS; |
340 | 0 | TEST(algorithm); |
341 | 0 | blockSize = CryptGetSymmetricBlockSize(algorithm, keySizeInBits); |
342 | 0 | if(blockSize == 0) |
343 | 0 | return TPM_RC_FAILURE; |
344 | | // If the iv is provided, then it is expected to be block sized. In some cases, |
345 | | // the caller is providing an array of 0's that is equal to [MAX_SYM_BLOCK_SIZE] |
346 | | // with no knowledge of the actual block size. This function will set it. |
347 | 0 | if((ivInOut != NULL) && (mode != ALG_ECB_VALUE)) |
348 | 0 | { |
349 | 0 | ivInOut->t.size = blockSize; |
350 | 0 | iv = ivInOut->t.buffer; |
351 | 0 | } |
352 | 0 | else |
353 | 0 | iv = defaultIv; |
354 | 0 | pIv = iv; |
355 | | // Use the mode to select the key schedule to create. Encrypt always uses the |
356 | | // encryption schedule. Depending on the mode, decryption might use either |
357 | | // the decryption or encryption schedule. |
358 | 0 | switch(mode) |
359 | 0 | { |
360 | 0 | #if ALG_CBC || ALG_ECB |
361 | 0 | case ALG_CBC_VALUE: // decrypt = decrypt |
362 | 0 | case ALG_ECB_VALUE: |
363 | | // For ECB and CBC, the data size must be an even multiple of the |
364 | | // cipher block size |
365 | 0 | if((dSize % blockSize) != 0) |
366 | 0 | return TPM_RC_SIZE; |
367 | 0 | SELECT(DECRYPT); |
368 | 0 | break; |
369 | 0 | #endif |
370 | 0 | default: |
371 | | // For the remaining stream ciphers, use encryption to decrypt |
372 | 0 | SELECT(ENCRYPT); |
373 | 0 | break; |
374 | 0 | } |
375 | | // Now do the mode-dependent decryption |
376 | 0 | switch(mode) |
377 | 0 | { |
378 | 0 | #if ALG_CBC |
379 | 0 | case ALG_CBC_VALUE: |
380 | | // Copy the input data to a temp buffer, decrypt the buffer into the |
381 | | // output, XOR in the IV, and copy the temp buffer to the IV and repeat. |
382 | 0 | for(; dSize > 0; dSize -= blockSize) |
383 | 0 | { |
384 | 0 | pT = tmp; |
385 | 0 | for(i = blockSize; i > 0; i--) |
386 | 0 | *pT++ = *dIn++; |
387 | 0 | DECRYPT(&keySchedule, tmp, dOut); |
388 | 0 | pIv = iv; |
389 | 0 | pT = tmp; |
390 | 0 | for(i = blockSize; i > 0; i--) |
391 | 0 | { |
392 | 0 | *dOut++ ^= *pIv; |
393 | 0 | *pIv++ = *pT++; |
394 | 0 | } |
395 | 0 | } |
396 | 0 | break; |
397 | 0 | #endif |
398 | 0 | case TPM_ALG_CFB: |
399 | 0 | for(; dSize > 0; dSize -= blockSize) |
400 | 0 | { |
401 | | // Encrypt the IV into the temp buffer |
402 | 0 | ENCRYPT(&keySchedule, iv, tmp); |
403 | 0 | pT = tmp; |
404 | 0 | pIv = iv; |
405 | 0 | for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--) |
406 | | // Copy the current cipher text to IV, XOR |
407 | | // with the temp buffer and put into the output |
408 | 0 | *dOut++ = *pT++ ^ (*pIv++ = *dIn++); |
409 | 0 | } |
410 | | // If the inner loop (i loop) was smaller than blockSize, then dSize |
411 | | // would have been smaller than blockSize and it is now negative |
412 | | // If it is negative, then it indicates how may fill bytes |
413 | | // are needed to pad out the IV for the next round. |
414 | 0 | for(; dSize < 0; dSize++) |
415 | 0 | *pIv++ = 0; |
416 | 0 | break; |
417 | 0 | #if ALG_CTR |
418 | 0 | case ALG_CTR_VALUE: |
419 | 0 | for(; dSize > 0; dSize -= blockSize) |
420 | 0 | { |
421 | | // Encrypt the current value of the IV(counter) |
422 | 0 | ENCRYPT(&keySchedule, iv, tmp); |
423 | | //increment the counter (counter is big-endian so start at end) |
424 | 0 | for(i = blockSize - 1; i >= 0; i--) |
425 | 0 | if((iv[i] += 1) != 0) |
426 | 0 | break; |
427 | | // XOR the encrypted counter value with input and put into output |
428 | 0 | pT = tmp; |
429 | 0 | for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--) |
430 | 0 | *dOut++ = *dIn++ ^ *pT++; |
431 | 0 | } |
432 | 0 | break; |
433 | 0 | #endif |
434 | 0 | #if ALG_ECB |
435 | 0 | case ALG_ECB_VALUE: |
436 | 0 | for(; dSize > 0; dSize -= blockSize) |
437 | 0 | { |
438 | 0 | DECRYPT(&keySchedule, dIn, dOut); |
439 | 0 | dIn = &dIn[blockSize]; |
440 | 0 | dOut = &dOut[blockSize]; |
441 | 0 | } |
442 | 0 | break; |
443 | 0 | #endif |
444 | 0 | #if ALG_OFB |
445 | 0 | case TPM_ALG_OFB: |
446 | | // This is written so that dIn and dOut may be the same |
447 | 0 | for(; dSize > 0; dSize -= blockSize) |
448 | 0 | { |
449 | | // Encrypt the current value of the "IV" |
450 | 0 | ENCRYPT(&keySchedule, iv, iv); |
451 | | // XOR the encrypted IV into dIn to create the cipher text (dOut) |
452 | 0 | pIv = iv; |
453 | 0 | for(i = (dSize < blockSize) ? dSize : blockSize; i > 0; i--) |
454 | 0 | *dOut++ = (*pIv++ ^ *dIn++); |
455 | 0 | } |
456 | 0 | break; |
457 | 0 | #endif |
458 | 0 | default: |
459 | 0 | return TPM_RC_FAILURE; |
460 | 0 | } |
461 | 0 | return TPM_RC_SUCCESS; |
462 | 0 | } |
463 | | /* 10.2.20.5.2 CryptSymKeyValidate() */ |
464 | | /* Validate that a provided symmetric key meets the requirements of the TPM */ |
465 | | /* Error Returns Meaning */ |
466 | | /* TPM_RC_KEY_SIZE Key size specifiers do not match */ |
467 | | /* TPM_RC_KEY Key is not allowed */ |
468 | | TPM_RC |
469 | | CryptSymKeyValidate( |
470 | | TPMT_SYM_DEF_OBJECT *symDef, |
471 | | TPM2B_SYM_KEY *key |
472 | | ) |
473 | 0 | { |
474 | 0 | if(key->t.size != BITS_TO_BYTES(symDef->keyBits.sym)) |
475 | 0 | return TPM_RCS_KEY_SIZE; |
476 | | #if ALG_TDES |
477 | | if(symDef->algorithm == TPM_ALG_TDES && !CryptDesValidateKey(key)) |
478 | | return TPM_RCS_KEY; |
479 | | #endif // TPM_ALG_TDES |
480 | 0 | return TPM_RC_SUCCESS; |
481 | 0 | } |