From c529f936467bf56f12a05c51ae3f1b82ee54a5ba Mon Sep 17 00:00:00 2001 From: Gregg Date: Wed, 27 Dec 2023 21:45:09 -0600 Subject: [PATCH] Moved definitions of N3072 and other constants into SRP6A structure --- src/HAP.cpp | 4 ++-- src/SRP.cpp | 47 ++++++++++++++++++----------------------------- src/SRP.h | 50 +++++++++++++++++++++++--------------------------- 3 files changed, 43 insertions(+), 58 deletions(-) diff --git a/src/HAP.cpp b/src/HAP.cpp index 9e70e34..2bb4399 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -388,8 +388,8 @@ int HAPClient::postPairSetupURL(uint8_t *content, size_t len){ srp=new SRP6A; // create instance of SRP to persist until Pairing is fully complete TempBuffer verifyData; // temporary storage for verification data - size_t len=sizeof(Verification); - nvs_get_blob(srpNVS,"VERIFYDATA",verifyData.get(),&len); // load verification data (should already be stored in NVS) + size_t len=verifyData.len(); + nvs_get_blob(srpNVS,"VERIFYDATA",verifyData,&len); // load verification data (should already be stored in NVS) srp->createPublicKey(verifyData.get()->verifyCode,verifyData.get()->salt); // create accessory Public Key from stored verification data (which was originally derived from Pair-Setup Code) mbedtls_mpi_write_binary(&srp->B,*itPublicKey,(*itPublicKey).len); // write resulting server PublicKey, B, into TLV mbedtls_mpi_write_binary(&srp->s,*itSalt,(*itSalt).len); // write Salt, s, into TLV diff --git a/src/SRP.cpp b/src/SRP.cpp index 0fc8ffd..3175be9 100644 --- a/src/SRP.cpp +++ b/src/SRP.cpp @@ -61,7 +61,7 @@ SRP6A::SRP6A(){ // load N and g into MPI structures mbedtls_mpi_read_string(&N,16,N3072); - mbedtls_mpi_lset(&g,5); + mbedtls_mpi_lset(&g,g3072); } @@ -99,15 +99,17 @@ void SRP6A::createVerifyCode(const char *setupCode, uint8_t *verifyCode, uint8_t TempBuffer tHash(64); // temporary buffer for storing SHA-512 results char *icp; // storage for I:P - randombytes_buf(salt,16); // generate 16 random bytes for salt - mbedtls_mpi_read_binary(&s,salt,16); // load salt into s - Serial.printf("*** SALT GENERATION: ");print(&s); + // generate random salt, s - asprintf(&icp,"Pair-Setup:%.3s-%.2s-%.3s",setupCode,setupCode+3,setupCode+5); + randombytes_buf(salt,16); // generate 16 random bytes for salt + + // create I:P + + asprintf(&icp,"%s:%.3s-%.2s-%.3s",I,setupCode,setupCode+3,setupCode+5); // compute x = SHA512( s | SHA512( I | ":" | P ) ) - mbedtls_mpi_write_binary(&s,tBuf,16); // write s into first 16 bytes of staging buffer + memcpy(tBuf,salt,16); // write salt into first 16 bytes of staging buffer mbedtls_sha512_ret((uint8_t *)icp,strlen(icp),tBuf+16,0); // create hash of username:password and write into last 64 bytes of staging buffer mbedtls_sha512_ret(tBuf,80,tHash,0); // create second hash of salted, hashed username:password mbedtls_mpi_read_binary(&x,tHash,64); // load hash result into x @@ -122,23 +124,18 @@ void SRP6A::createVerifyCode(const char *setupCode, uint8_t *verifyCode, uint8_t ////////////////////////////////////// -//void SRP6A::loadVerifyCode(uint8_t *verifyCode, uint8_t *salt){ -// -// mbedtls_mpi_read_binary(&s,salt,16); -// mbedtls_mpi_read_binary(&v,verifyCode,384); -// -//} - -////////////////////////////////////// - void SRP6A::createPublicKey(const uint8_t *verifyCode, const uint8_t *salt){ TempBuffer tBuf(768); // temporary buffer for staging TempBuffer tHash(64); // temporary buffer for storing SHA-512 results TempBuffer privateKey(32); // temporary buffer for generating private key random numbers + // load stored salt, s, and verification code, v + mbedtls_mpi_read_binary(&s,salt,16); // load salt into s for use in later steps mbedtls_mpi_read_binary(&v,verifyCode,384); // load verifyCode into v for use below + + // generate random private key, b randombytes_buf(privateKey,32); // generate 32 random bytes for private key mbedtls_mpi_read_binary(&b,privateKey,32); // load private key into b @@ -157,22 +154,10 @@ void SRP6A::createPublicKey(const uint8_t *verifyCode, const uint8_t *salt){ mbedtls_mpi_add_mpi(&t3,&t1,&t2); // t3 = t1 + t2 mbedtls_mpi_mod_mpi(&B,&t3,&N); // B = t3 %N = ACCESSORY PUBLIC KEY - print(&s); - } ////////////////////////////////////// -//void SRP6A::getPrivateKey(){ -// -// uint8_t privateKey[32]; -// -// randombytes_buf(privateKey,32); // generate 32 random bytes using libsodium (which uses the ESP32 hardware-based random number generator) -// mbedtls_mpi_read_binary(&b,privateKey,32); -//} - -////////////////////////////////////// - void SRP6A::createSessionKey(){ uint8_t tBuf[768]; // temporary buffer for staging @@ -209,12 +194,12 @@ int SRP6A::verifyProof(){ uint8_t tBuf[976]; // temporary buffer for staging uint8_t tHash[64]; // temporary buffer for storing SHA-512 results - size_t count=0; // total number of bytes for final hash + size_t count=0; // total number of bytes for final hash size_t sLen; mbedtls_mpi_write_binary(&N,tBuf,384); // write N into staging buffer mbedtls_sha512_ret(tBuf,384,tHash,0); // create hash of data - mbedtls_sha512_ret((uint8_t *)g3072,1,tBuf,0); // create hash of g, but place output directly into staging buffer + mbedtls_sha512_ret(&g3072,1,tBuf,0); // create hash of g, but place output directly into staging buffer for(int i=0;i<64;i++) // H(g) -> H(g) XOR H(N), with results in first 64 bytes of staging buffer tBuf[i]^=tHash[i]; @@ -273,3 +258,7 @@ void SRP6A::print(mbedtls_mpi *mpi){ } ////////////////////////////////////// + +constexpr char SRP6A::N3072[]; +constexpr char SRP6A::I[]; +const uint8_t SRP6A::g3072; diff --git a/src/SRP.h b/src/SRP.h index e92249f..2f51b63 100644 --- a/src/SRP.h +++ b/src/SRP.h @@ -45,27 +45,30 @@ ///////////////////////////////////////////////// // SRP-6A Structure from RFC 5054 (Nov 2007) -// ** HAP uses N=3072-bit Group specified in RFC 5054 +// ** HAP uses N=3072-bit Group specified in RFC 5054 with Generator g=5 // ** HAP replaces H=SHA-1 with H=SHA-512 (HAP Section 5.5) // // I = SRP-6A username, defined by HAP to be the word "Pair-Setup" // P = SRP-6A password, defined to be equal to the accessory's 8-digit setup code in the format "XXX-XX-XXX" -const char N3072[]="FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74" - "020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437" - "4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" - "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05" - "98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB" - "9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" - "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" - "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33" - "A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" - "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864" - "D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2" - "08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; - struct SRP6A { + static constexpr char N3072[]="FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74" + "020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437" + "4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05" + "98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB" + "9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33" + "A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864" + "D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2" + "08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; + + static const uint8_t g3072=5; + static constexpr char I[]="Pair-Setup"; + mbedtls_mpi N; // N - 3072-bit Group pre-defined prime used for all SRP-6A calculations (384 bytes) mbedtls_mpi g; // g - pre-defined generator for the specified 3072-bit Group (g=5) mbedtls_mpi k; // k = H(N | PAD(g)) - SRP-6A multiplier (which is different from versions SRP-6 or SRP-3) @@ -88,9 +91,6 @@ struct SRP6A { mbedtls_mpi _rr; // _rr - temporary "helper" for large exponential modulus calculations - char I[11]="Pair-Setup"; // I - userName pre-defined by HAP pairing setup protocol - char g3072[2]="\x05"; // g - 3072-bit Group generator - uint8_t sharedSecret[64]; // permanent storage for binary version of SHARED SECRET KEY for ease of use upstream SRP6A(); // initializes N, G, and computes k @@ -98,16 +98,12 @@ struct SRP6A { void *operator new(size_t size){return(HS_MALLOC(size));} // override new operator to use PSRAM when available - void createVerifyCode(const char *setupCode, uint8_t *verifyCode, uint8_t *salt); -// void loadVerifyCode(uint8_t *verifyCode, uint8_t *salt); - -// void getPrivateKey(); // generates and stores random 32-byte private key, b -// void getSetupCode(char *c); // generates and displays random 8-digit Pair-Setup code, P, in format XXX-XX-XXX - void createPublicKey(const uint8_t *verifyCode, const uint8_t *salt); // computes x, v, and B from random s, P, and b - void createSessionKey(); // computes u from A and B, and then S from A, v, u, and b - int verifyProof(); // verify M1 SRP6A Proof received from HAP client (return 1 on success, 0 on failure) - void createProof(); // create M2 server-side SRP6A Proof based on M1 as received from HAP Client + void createVerifyCode(const char *setupCode, uint8_t *verifyCode, uint8_t *salt); // generates random s and computes v from specified 8-digit Pairing-Setup Code + void createPublicKey(const uint8_t *verifyCode, const uint8_t *salt); // generates random b and computes k and B from specified v and s + void createSessionKey(); // computes u from A and B, and then S from A, v, u, and b + int verifyProof(); // verify M1 SRP6A Proof received from HAP client (return 1 on success, 0 on failure) + void createProof(); // create M2 server-side SRP6A Proof based on M1 as received from HAP Client - void print(mbedtls_mpi *mpi); // prints size of mpi (in bytes), followed by the mpi itself (as a hex charcter string) + void print(mbedtls_mpi *mpi); // prints size of mpi (in bytes), followed by the mpi itself (as a hex character string) };