1// This file was extracted from the TCG Published 2// Trusted Platform Module Library 3// Part 3: Commands 4// Family "2.0" 5// Level 00 Revision 01.16 6// October 30, 2014 7 8#include "InternalRoutines.h" 9#include "ECDH_KeyGen_fp.h" 10#ifdef TPM_ALG_ECC 11// 12// 13// Error Returns Meaning 14// 15// TPM_RC_KEY keyHandle does not reference a non-restricted decryption ECC key 16// 17TPM_RC 18TPM2_ECDH_KeyGen( 19 ECDH_KeyGen_In *in, // IN: input parameter list 20 ECDH_KeyGen_Out *out // OUT: output parameter list 21 ) 22{ 23 OBJECT *eccKey; 24 TPM2B_ECC_PARAMETER sensitive; 25 TPM_RC result; 26 27// Input Validation 28 29 eccKey = ObjectGet(in->keyHandle); 30 31 // Input key must be a non-restricted, decrypt ECC key 32 if( eccKey->publicArea.type != TPM_ALG_ECC) 33 return TPM_RC_KEY + RC_ECDH_KeyGen_keyHandle; 34 35 if( eccKey->publicArea.objectAttributes.restricted == SET 36 || eccKey->publicArea.objectAttributes.decrypt != SET 37 ) 38 return TPM_RC_KEY + RC_ECDH_KeyGen_keyHandle; 39 40// Command Output 41 do 42 { 43 // Create ephemeral ECC key 44 CryptNewEccKey(eccKey->publicArea.parameters.eccDetail.curveID, 45 &out->pubPoint.t.point, &sensitive); 46 47 out->pubPoint.t.size = TPMS_ECC_POINT_Marshal(&out->pubPoint.t.point, 48 NULL, NULL); 49 50 // Compute Z 51 result = CryptEccPointMultiply(&out->zPoint.t.point, 52 eccKey->publicArea.parameters.eccDetail.curveID, 53 &sensitive, &eccKey->publicArea.unique.ecc); 54 // The point in the key is not on the curve. Indicate that the key is bad. 55 if(result == TPM_RC_ECC_POINT) 56 return TPM_RC_KEY + RC_ECDH_KeyGen_keyHandle; 57 // The other possible error is TPM_RC_NO_RESULT indicating that the 58 // multiplication resulted in the point at infinity, so get a new 59 // random key and start over (hardly ever happens). 60 } 61 while(result == TPM_RC_NO_RESULT); 62 63 if(result == TPM_RC_SUCCESS) 64 // Marshal the values to generate the point. 65 out->zPoint.t.size = TPMS_ECC_POINT_Marshal(&out->zPoint.t.point, 66 NULL, NULL); 67 68 return result; 69} 70#endif 71