Changed TLV:add() so it returns TLV8 instead of iterator.

Makes it easier to chain .add() functions as well as dynamically create sub TLVs.

Changing TLV8::add() in this fashion also required updating various use cases of TLV::add() in HAP.cpp where add() was used to reserve space for a blank TLV element.  All changes have been tested.
This commit is contained in:
Gregg 2024-04-13 19:12:26 -05:00
parent 5ded77d6d9
commit 7a50479bac
3 changed files with 27 additions and 30 deletions

View File

@ -370,7 +370,6 @@ int HAPClient::postPairSetupURL(uint8_t *content, size_t len){
return(0);
};
auto itPublicKey=responseTLV.add(kTLVType_PublicKey,384,NULL); // create blank PublicKey TLV with space for 384 bytes
if(srp==NULL) // create instance of SRP (if not already created) to persist until Pairing-Setup M5 completes
srp=new SRP6A;
@ -381,7 +380,8 @@ int HAPClient::postPairSetupURL(uint8_t *content, size_t len){
responseTLV.add(kTLVType_Salt,16,verifyData.get()->salt); // write Salt from verification data into TLV
srp->createPublicKey(verifyData,*itPublicKey); // create accessory Public Key from stored verification data and write result into PublicKey TLV
responseTLV.add(kTLVType_PublicKey,384,NULL); // create blank PublicKey TLV with space for 384 bytes
srp->createPublicKey(verifyData,responseTLV.back()); // create accessory Public Key from stored verification data and write result into PublicKey TLV
tlvRespond(responseTLV); // send response to client
pairStatus=pairState_M3; // set next expected pair-state request from client
@ -414,9 +414,8 @@ int HAPClient::postPairSetupURL(uint8_t *content, size_t len){
return(0);
};
auto itAccProof=responseTLV.add(kTLVType_Proof,64,NULL); // create blank accessory Proof TLV with space for 64 bytes
srp->createAccProof(*itAccProof); // M1 has been successully verified; now create accessory Proof M2
responseTLV.add(kTLVType_Proof,64,NULL); // create blank accessory Proof TLV with space for 64 bytes
srp->createAccProof(responseTLV.back()); // M1 has been successully verified; now create accessory Proof M2
tlvRespond(responseTLV); // send response to client
pairStatus=pairState_M5; // set next expected pair-state request from client
@ -515,9 +514,8 @@ int HAPClient::postPairSetupURL(uint8_t *content, size_t len){
subTLV.clear(); // clear existing SUBTLV records
itSignature=subTLV.add(kTLVType_Signature,64,NULL); // create blank Signature TLV with space for 64 bytes
crypto_sign_detached(*itSignature,NULL,accessoryInfo,accessoryInfo.len(),accessory.LTSK); // produce signature of accessoryInfo using AccessoryLTSK (Ed25519 long-term secret key)
subTLV.add(kTLVType_Signature,64,NULL); // create blank Signature TLV with space for 64 bytes
crypto_sign_detached(subTLV.back(),NULL,accessoryInfo,accessoryInfo.len(),accessory.LTSK); // produce signature of accessoryInfo using AccessoryLTSK (Ed25519 long-term secret key)
subTLV.add(kTLVType_Identifier,hap_accessory_IDBYTES,accessory.ID); // set Identifier TLV record as accessoryPairingID
subTLV.add(kTLVType_PublicKey,crypto_sign_PUBLICKEYBYTES,accessory.LTPK); // set PublicKey TLV record as accessoryLTPK
@ -532,9 +530,9 @@ int HAPClient::postPairSetupURL(uint8_t *content, size_t len){
// Encrypt the subTLV data using the same SRP Session Key as above with ChaCha20-Poly1305
itEncryptedData=responseTLV.add(kTLVType_EncryptedData,subPack.len()+crypto_aead_chacha20poly1305_IETF_ABYTES,NULL); //create blank EncryptedData TLV with space for subTLV + Authentication Tag
responseTLV.add(kTLVType_EncryptedData,subPack.len()+crypto_aead_chacha20poly1305_IETF_ABYTES,NULL); //create blank EncryptedData TLV with space for subTLV + Authentication Tag
crypto_aead_chacha20poly1305_ietf_encrypt(*itEncryptedData,NULL,subPack,subPack.len(),NULL,0,NULL,(unsigned char *)"\x00\x00\x00\x00PS-Msg06",sessionKey);
crypto_aead_chacha20poly1305_ietf_encrypt(responseTLV.back(),NULL,subPack,subPack.len(),NULL,0,NULL,(unsigned char *)"\x00\x00\x00\x00PS-Msg06",sessionKey);
LOG2("---------- END SUB-TLVS! ----------\n");
@ -623,8 +621,8 @@ int HAPClient::postPairVerifyURL(uint8_t *content, size_t len){
TempBuffer<uint8_t> accessoryInfo(publicCurveKey,crypto_box_PUBLICKEYBYTES,accessory.ID,hap_accessory_IDBYTES,iosCurveKey,crypto_box_PUBLICKEYBYTES,NULL);
subTLV.add(kTLVType_Identifier,hap_accessory_IDBYTES,accessory.ID); // set Identifier subTLV record as Accessory's Pairing ID
auto itSignature=subTLV.add(kTLVType_Signature,crypto_sign_BYTES,NULL); // create blank Signature subTLV
crypto_sign_detached(*itSignature,NULL,accessoryInfo,accessoryInfo.len(),accessory.LTSK); // produce Signature of accessoryInfo using Accessory's LTSK
subTLV.add(kTLVType_Signature,crypto_sign_BYTES,NULL); // create blank Signature subTLV
crypto_sign_detached(subTLV.back(),NULL,accessoryInfo,accessoryInfo.len(),accessory.LTSK); // produce Signature of accessoryInfo using Accessory's LTSK
LOG2("------- ENCRYPTING SUB-TLVS -------\n");
@ -640,8 +638,8 @@ int HAPClient::postPairVerifyURL(uint8_t *content, size_t len){
sessionKey=(uint8_t *)HS_MALLOC(crypto_box_PUBLICKEYBYTES); // temporary space - will be deleted at end of verification process
HKDF::create(sessionKey,sharedCurveKey,crypto_box_PUBLICKEYBYTES,"Pair-Verify-Encrypt-Salt","Pair-Verify-Encrypt-Info"); // create Session Curve25519 Key from Shared-Secret Curve25519 Key using HKDF-SHA-512
auto itEncryptedData=responseTLV.add(kTLVType_EncryptedData,subPack.len()+crypto_aead_chacha20poly1305_IETF_ABYTES,NULL); // create blank EncryptedData subTLV
crypto_aead_chacha20poly1305_ietf_encrypt(*itEncryptedData,NULL,subPack,subPack.len(),NULL,0,NULL,(unsigned char *)"\x00\x00\x00\x00PV-Msg02",sessionKey); // encrypt data with Session Curve25519 Key and padded nonce="PV-Msg02"
responseTLV.add(kTLVType_EncryptedData,subPack.len()+crypto_aead_chacha20poly1305_IETF_ABYTES,NULL); // create blank EncryptedData subTLV
crypto_aead_chacha20poly1305_ietf_encrypt(responseTLV.back(),NULL,subPack,subPack.len(),NULL,0,NULL,(unsigned char *)"\x00\x00\x00\x00PV-Msg02",sessionKey); // encrypt data with Session Curve25519 Key and padded nonce="PV-Msg02"
LOG2("---------- END SUB-TLVS! ----------\n");

View File

@ -68,28 +68,27 @@ void tlv8_t::osprint(std::ostream& os){
/////////////////////////////////////
TLV8_it TLV8::add(uint8_t tag, size_t len, const uint8_t* val){
TLV8 &TLV8::add(uint8_t tag, size_t len, const uint8_t* val){
if(!empty() && back().tag==tag)
back().update(len,val);
else
emplace_back(tag,len,val);
return(--end());
return(*this);
}
/////////////////////////////////////
TLV8_it TLV8::add(uint8_t tag, TLV8 &subTLV){
TLV8 &TLV8::add(uint8_t tag, TLV8 &subTLV){
auto it=add(tag,subTLV.pack_size(),NULL); // create space for inserting sub TLV and store iterator to new element
subTLV.pack(*it); // pack subTLV into new element
return(--end());
subTLV.pack(add(tag,subTLV.pack_size(),NULL).back()); // add new blank element of sufficient size and pack subTLV into this new element
return(*this);
}
/////////////////////////////////////
TLV8_it TLV8::add(uint8_t tag, uint64_t val){
TLV8 &TLV8::add(uint8_t tag, uint64_t val){
uint8_t *p=reinterpret_cast<uint8_t *>(&val);
size_t nBytes=sizeof(uint64_t);
@ -105,7 +104,7 @@ TLV8_it TLV8::find(uint8_t tag, TLV8_it it1, TLV8_it it2){
auto it=it1;
while(it!=it2 && (*it).tag!=tag)
it++;
return(it==it2?end():it);
return(it);
}
/////////////////////////////////////

View File

@ -84,11 +84,11 @@ class TLV8 : public std::list<tlv8_t, Mallocator<tlv8_t>> {
TLV8(){};
TLV8(const TLV8_names *names, int nNames) : names{names}, nNames{nNames} {};
TLV8_it add(uint8_t tag, size_t len, const uint8_t *val);
TLV8_it add(uint8_t tag, uint64_t val);
TLV8_it add(uint8_t tag, TLV8 &subTLV);
TLV8_it add(uint8_t tag){return(add(tag, 0, NULL));}
TLV8_it add(uint8_t tag, const char *val){return(add(tag, strlen(val), reinterpret_cast<const uint8_t*>(val)));}
TLV8 & add(uint8_t tag, size_t len, const uint8_t *val);
TLV8 & add(uint8_t tag, uint64_t val);
TLV8 & add(uint8_t tag, TLV8 &subTLV);
TLV8 & add(uint8_t tag){return(add(tag, 0, NULL));}
TLV8 & add(uint8_t tag, const char *val){return(add(tag, strlen(val), reinterpret_cast<const uint8_t*>(val)));}
TLV8_it find(uint8_t tag, TLV8_it it1, TLV8_it it2);
TLV8_it find(uint8_t tag, TLV8_it it1){return(find(tag, it1, end()));}