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 "ZGen_2Phase_fp.h" 10#ifdef TPM_CC_ZGen_2Phase // Conditional expansion of this file 11// 12// This command uses the TPM to recover one or two Z values in a two phase key exchange protocol 13// 14// Error Returns Meaning 15// 16// TPM_RC_ATTRIBUTES key referenced by keyA is restricted or not a decrypt key 17// TPM_RC_ECC_POINT inQsB or inQeB is not on the curve of the key reference by keyA 18// TPM_RC_KEY key referenced by keyA is not an ECC key 19// TPM_RC_SCHEME the scheme of the key referenced by keyA is not TPM_ALG_NULL, 20// TPM_ALG_ECDH, TPM_ALG_ECMQV or TPM_ALG_SM2 21// 22TPM_RC 23TPM2_ZGen_2Phase( 24 ZGen_2Phase_In *in, // IN: input parameter list 25 ZGen_2Phase_Out *out // OUT: output parameter list 26 ) 27{ 28 TPM_RC result; 29 OBJECT *eccKey; 30 TPM2B_ECC_PARAMETER r; 31 TPM_ALG_ID scheme; 32 33// Input Validation 34 35 eccKey = ObjectGet(in->keyA); 36 37 // keyA must be an ECC key 38 if(eccKey->publicArea.type != TPM_ALG_ECC) 39 return TPM_RC_KEY + RC_ZGen_2Phase_keyA; 40 41 // keyA must not be restricted and must be a decrypt key 42 if( eccKey->publicArea.objectAttributes.restricted == SET 43 || eccKey->publicArea.objectAttributes.decrypt != SET 44 ) 45 return TPM_RC_ATTRIBUTES + RC_ZGen_2Phase_keyA; 46 47 // if the scheme of keyA is TPM_ALG_NULL, then use the input scheme; otherwise 48 // the input scheme must be the same as the scheme of keyA 49 scheme = eccKey->publicArea.parameters.asymDetail.scheme.scheme; 50 if(scheme != TPM_ALG_NULL) 51 { 52 if(scheme != in->inScheme) 53 return TPM_RC_SCHEME + RC_ZGen_2Phase_inScheme; 54 } 55 else 56 scheme = in->inScheme; 57 if(scheme == TPM_ALG_NULL) 58 return TPM_RC_SCHEME + RC_ZGen_2Phase_inScheme; 59 60 // Input points must be on the curve of keyA 61 if(!CryptEccIsPointOnCurve(eccKey->publicArea.parameters.eccDetail.curveID, 62 &in->inQsB.t.point)) 63 return TPM_RC_ECC_POINT + RC_ZGen_2Phase_inQsB; 64 65 if(!CryptEccIsPointOnCurve(eccKey->publicArea.parameters.eccDetail.curveID, 66 &in->inQeB.t.point)) 67// 68 return TPM_RC_ECC_POINT + RC_ZGen_2Phase_inQeB; 69 70 if(!CryptGenerateR(&r, &in->counter, 71 eccKey->publicArea.parameters.eccDetail.curveID, 72 NULL)) 73 return TPM_RC_VALUE + RC_ZGen_2Phase_counter; 74 75// Command Output 76 77 result = CryptEcc2PhaseKeyExchange(&out->outZ1.t.point, 78 &out->outZ2.t.point, 79 eccKey->publicArea.parameters.eccDetail.curveID, 80 scheme, 81 &eccKey->sensitive.sensitive.ecc, 82 &r, 83 &in->inQsB.t.point, 84 &in->inQeB.t.point); 85 if(result == TPM_RC_SCHEME) 86 return TPM_RC_SCHEME + RC_ZGen_2Phase_inScheme; 87 88 if(result == TPM_RC_SUCCESS) 89 CryptEndCommit(in->counter); 90 91 return result; 92} 93#endif 94