From 3aa545688182333ed3f1da26f4582d58c2f11ede Mon Sep 17 00:00:00 2001 From: Gregg Date: Sat, 2 Jan 2021 21:18:50 -0600 Subject: [PATCH] Fixed memory problem with sendEncrypyted() Switched from using fixed buffer, httpBuf, to a TempBuffer to allow for dynamic allocation of memory when assembling and transmitting large blocks of data. This was causing a memory overflow of the static httpBuf when responding to a getAccessories() request for a large number of Accessories. --- src/HAP.cpp | 24 ++++++++++++++++-------- src/Utils.h | 8 +++++++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/HAP.cpp b/src/HAP.cpp index b351467..150a8df 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -1381,10 +1381,18 @@ void HAPClient::sendEncrypted(char *body, uint8_t *dataBuf, int dataLen){ int count=0; unsigned long long nBytes; - httpBuf[count]=bodyLen%256; // store number of bytes in first frame that encrypts the Body (AAD bytes) - httpBuf[count+1]=bodyLen/256; + int totalBytes=2+bodyLen+16; // 2-byte AAD + bodyLen + 16-byte authentication tag + totalBytes+=(dataLen/FRAME_SIZE)*(2+FRAME_SIZE+16); // number of full frames * size of full frame with 2-byte AAD + 16-byte authentication tag + + if(dataLen%FRAME_SIZE) // if there is a residual last partial frame + totalBytes+=2+dataLen%FRAME_SIZE+16; // 2-byte AAD + residual of last partial frame + 16-byte authentication tag + + TempBuffer tBuf(totalBytes); - crypto_aead_chacha20poly1305_ietf_encrypt(httpBuf+count+2,&nBytes,(uint8_t *)body,bodyLen,httpBuf+count,2,NULL,a2cNonce.get(),a2cKey); // encrypt the Body with authentication tag appended + tBuf.buf[count]=bodyLen%256; // store number of bytes in first frame that encrypts the Body (AAD bytes) + tBuf.buf[count+1]=bodyLen/256; + + crypto_aead_chacha20poly1305_ietf_encrypt(tBuf.buf+count+2,&nBytes,(uint8_t *)body,bodyLen,tBuf.buf+count,2,NULL,a2cNonce.get(),a2cKey); // encrypt the Body with authentication tag appended a2cNonce.inc(); // increment nonce @@ -1397,17 +1405,17 @@ void HAPClient::sendEncrypted(char *body, uint8_t *dataBuf, int dataLen){ if(n>FRAME_SIZE) // maximum number of bytes to encrypt=FRAME_SIZE n=FRAME_SIZE; - httpBuf[count]=n%256; // store number of bytes that encrypts this frame (AAD bytes) - httpBuf[count+1]=n/256; + tBuf.buf[count]=n%256; // store number of bytes that encrypts this frame (AAD bytes) + tBuf.buf[count+1]=n/256; - crypto_aead_chacha20poly1305_ietf_encrypt(httpBuf+count+2,&nBytes,dataBuf+i,n,httpBuf+count,2,NULL,a2cNonce.get(),a2cKey); // encrypt the next portion of dataBuf with authentication tag appended + crypto_aead_chacha20poly1305_ietf_encrypt(tBuf.buf+count+2,&nBytes,dataBuf+i,n,tBuf.buf+count,2,NULL,a2cNonce.get(),a2cKey); // encrypt the next portion of dataBuf with authentication tag appended a2cNonce.inc(); // increment nonce count+=2+n+16; // increment count by 2-byte AAD record + length of JSON + 16-byte authentication tag } - - client.write(httpBuf,count); // transmit all encrypted frames to Client + + client.write(tBuf.buf,count); // transmit all encrypted frames to Client LOG2("-------- SENT ENCRYPTED! --------\n"); diff --git a/src/Utils.h b/src/Utils.h index cfd4de9..c311297 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -48,7 +48,13 @@ struct TempBuffer { TempBuffer(size_t len){ nBytes=len*sizeof(bufType); - buf=(bufType *)heap_caps_malloc(nBytes,MALLOC_CAP_8BIT); + buf=(bufType *)heap_caps_malloc(nBytes,MALLOC_CAP_8BIT); + if(buf==NULL){ + Serial.print("\n\n*** FATAL ERROR: Requested allocation of "); + Serial.print(nBytes); + Serial.print(" bytes failed. Program Halting.\n\n"); + while(1); + } } ~TempBuffer(){