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_ATTRIBUTES If the key is restricted or the key is not a decryption key 16 // TPM_RC_KEY keyHandle does not reference a non-restricted decryption ECC key 17 // 18 TPM_RC 19 TPM2_ECDH_KeyGen( 20 ECDH_KeyGen_In *in, // IN: input parameter list 21 ECDH_KeyGen_Out *out // OUT: output parameter list 22 ) 23 { 24 OBJECT *eccKey; 25 TPM2B_ECC_PARAMETER sensitive; 26 TPM_RC result; 27 28 // Input Validation 29 30 eccKey = ObjectGet(in->keyHandle); 31 32 // Input key must be a non-restricted, decrypt ECC key 33 if( eccKey->publicArea.type != TPM_ALG_ECC) 34 return TPM_RC_KEY + RC_ECDH_KeyGen_keyHandle; 35 36 if( eccKey->publicArea.objectAttributes.restricted == SET 37 || eccKey->publicArea.objectAttributes.decrypt != SET 38 ) 39 return TPM_RC_ATTRIBUTES + RC_ECDH_KeyGen_keyHandle; 40 41 // Command Output 42 do 43 { 44 // Create ephemeral ECC key 45 CryptNewEccKey(eccKey->publicArea.parameters.eccDetail.curveID, 46 &out->pubPoint.t.point, &sensitive); 47 48 out->pubPoint.t.size = TPMS_ECC_POINT_Marshal(&out->pubPoint.t.point, 49 NULL, NULL); 50 51 // Compute Z 52 result = CryptEccPointMultiply(&out->zPoint.t.point, 53 eccKey->publicArea.parameters.eccDetail.curveID, 54 &sensitive, &eccKey->publicArea.unique.ecc); 55 // The point in the key is not on the curve. Indicate that the key is bad. 56 if(result == TPM_RC_ECC_POINT) 57 return TPM_RC_KEY + RC_ECDH_KeyGen_keyHandle; 58 // The other possible error is TPM_RC_NO_RESULT indicating that the 59 // multiplication resulted in the point at infinity, so get a new 60 // random key and start over (hardly ever happens). 61 } 62 while(result == TPM_RC_NO_RESULT); 63 64 if(result == TPM_RC_SUCCESS) 65 // Marshal the values to generate the point. 66 out->zPoint.t.size = TPMS_ECC_POINT_Marshal(&out->zPoint.t.point, 67 NULL, NULL); 68 69 return result; 70 } 71 #endif 72