Skip to content

Commit

Permalink
Added SHA-384 hash computation to HapOut
Browse files Browse the repository at this point in the history
Hashing of entire database is now done piecemeal within HapOut, preventing the need to load the entire database into a large buffer just to obtain a unique hash.

Modified updateDatabase() to use HapOut.getHash()
  • Loading branch information
HomeSpan committed Dec 31, 2023
1 parent f2cb880 commit 1f13906
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 36 deletions.
40 changes: 16 additions & 24 deletions src/HAP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -912,24 912,6 @@ int HAPClient::getAccessoriesURL(){
hapOut.flush();

LOG2("\n-------- SENT ENCRYPTED! --------\n");


// int nBytes = homeSpan.sprintfAttributes(NULL); // get size of HAP attributes JSON
// TempBuffer<char> jBuf(nBytes 1);
// homeSpan.sprintfAttributes(jBuf); // create JSON database (will need to re-cast to uint8_t* below)

// char *body;
// asprintf(&body,"HTTP/1.1 200 OK\r\nContent-Type: application/hap json\r\nContent-Length: %d\r\n\r\n",nBytes);

// LOG2("\n>>>>>>>>>> ");
// LOG2(client.remoteIP());
// LOG2(" >>>>>>>>>>\n");
// LOG2(body);
// LOG2(jBuf.get());
// LOG2("\n");

// sendEncrypted(body,(uint8_t *)jBuf.get(),nBytes);
// free(body);

return(1);

Expand Down Expand Up @@ -1648,8 1630,14 @@ void Nonce::inc(){

HapOut::HapStreamBuffer::HapStreamBuffer(){

buffer=(char *)HS_MALLOC(bufSize 1); // add 1 for adding null terminator when printing text
encBuf=(uint8_t *)HS_MALLOC(bufSize 18); // 2-byte AAD encrypted data 16-byte authentication tag
buffer=(char *)HS_MALLOC(bufSize 1); // add 1 for adding null terminator when printing text
encBuf=(uint8_t *)HS_MALLOC(bufSize 18); // 2-byte AAD encrypted data 16-byte authentication tag

hash=(uint8_t *)HS_MALLOC(48); // space for SHA-384 hash output
ctx = (mbedtls_sha512_context *)HS_MALLOC(sizeof(mbedtls_sha512_context)); // space for hash context
mbedtls_sha512_init(ctx); // initialize context
mbedtls_sha512_starts_ret(ctx,1); // start SHA-384 hash (note second argument=1)

setp(buffer, buffer bufSize-1);
}

Expand All @@ -1670,7 1658,7 @@ void HapOut::HapStreamBuffer::flushBuffer(){
byteCount =num;

if(logLevel<=homeSpan.getLogLevel()){
buffer[num]='\0';
buffer[num]='\0'; // add null terminator but DO NOT increment num (we don't want terminator considered as part of buffer)
Serial.print(buffer);
}

Expand All @@ -1687,11 1675,12 @@ void HapOut::HapStreamBuffer::flushBuffer(){
hapClient->client.write(encBuf,num 18); // transmit encrypted frame
hapClient->a2cNonce.inc(); // increment nonce
}

delay(1);
}

pbump(-num);

mbedtls_sha512_update_ret(ctx,(uint8_t *)buffer,num); // update hash

pbump(-num); // reset buffer pointers
}

//////////////////////////////////////
Expand All @@ -1718,6 1707,9 @@ int HapOut::HapStreamBuffer::sync(){
enablePrettyPrint=false;
byteCount=0;

mbedtls_sha512_finish_ret(ctx,hash); // finish SHA-384 and store hash
mbedtls_sha512_starts_ret(ctx,1); // re-start hash for next time

return(0);
}

Expand Down
5 changes: 4 additions & 1 deletion src/HAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 195,8 @@ class HapOut : public std::ostream {
int logLevel=255; // default is NOT to print anything
boolean enablePrettyPrint=false;
size_t byteCount=0;
uint8_t *hash;
mbedtls_sha512_context *ctx;

void flushBuffer();
int_type overflow(int_type c) override;
Expand All @@ -214,7 216,8 @@ class HapOut : public std::ostream {
HapOut& setHapClient(HAPClient *hapClient){hapBuffer.hapClient=hapClient;return(*this);}
HapOut& setLogLevel(int logLevel){hapBuffer.logLevel=logLevel;return(*this);}
HapOut& prettyPrint(){hapBuffer.enablePrettyPrint=true;hapBuffer.logLevel=0;return(*this);}


uint8_t *getHash(){return(hapBuffer.hash);}
size_t getSize(){return(hapBuffer.getSize());}
};

Expand Down
16 changes: 7 additions & 9 deletions src/HomeSpan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1619,18 1619,16 @@ int Span::sprintfAttributes(char **ids, int numIDs, int flags, char *cBuf){

boolean Span::updateDatabase(boolean updateMDNS){

uint8_t tHash[48];
TempBuffer<char> tBuf(sprintfAttributes(NULL,GET_META|GET_PERMS|GET_TYPE|GET_DESC) 1);
sprintfAttributes(tBuf,GET_META|GET_PERMS|GET_TYPE|GET_DESC);
mbedtls_sha512_ret((uint8_t *)tBuf.get(),tBuf.len(),tHash,1); // create SHA-384 hash of JSON (can be any hash - just looking for a unique key)
printfAttributes(GET_META|GET_PERMS|GET_TYPE|GET_DESC); // stream attributes database, which automtically produces a SHA-384 hash
hapOut.flush();

boolean changed=false;

if(memcmp(tHash,hapConfig.hashCode,48)){ // if hash code of current HAP database does not match stored hash code
memcpy(hapConfig.hashCode,tHash,48); // update stored hash code
hapConfig.configNumber ; // increment configuration number
if(hapConfig.configNumber==65536) // reached max value
hapConfig.configNumber=1; // reset to 1
if(memcmp(hapOut.getHash(),hapConfig.hashCode,48)){ // if hash code of current HAP database does not match stored hash code
memcpy(hapConfig.hashCode,hapOut.getHash(),48); // update stored hash code
hapConfig.configNumber ; // increment configuration number
if(hapConfig.configNumber==65536) // reached max value
hapConfig.configNumber=1; // reset to 1

nvs_set_blob(HAPClient::hapNVS,"HAPHASH",&hapConfig,sizeof(hapConfig)); // update data
nvs_commit(HAPClient::hapNVS); // commit to NVS
Expand Down
4 changes: 2 additions & 2 deletions src/src.ino
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 27,13 @@

#include "HomeSpan.h"

#define MAX_LIGHTS 3
#define MAX_LIGHTS 4

void setup() {

Serial.begin(115200);

homeSpan.setLogLevel(2);
homeSpan.setLogLevel(0);
homeSpan.enableWebLog(200);

homeSpan.begin(Category::Lighting,"HomeSpan Max");
Expand Down

0 comments on commit 1f13906

Please sign in to comment.