Moved definitions of N3072 and other constants into SRP6A structure

This commit is contained in:
Gregg 2023-12-27 21:45:09 -06:00
parent b960c2fdaf
commit c529f93646
3 changed files with 43 additions and 58 deletions

View File

@ -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<Verification> 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

View File

@ -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<uint8_t> 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,24 +124,19 @@ 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<uint8_t> tBuf(768); // temporary buffer for staging
TempBuffer<uint8_t> tHash(64); // temporary buffer for storing SHA-512 results
TempBuffer<uint8_t> 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
@ -214,7 +199,7 @@ int SRP6A::verifyProof(){
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;

View File

@ -45,13 +45,15 @@
/////////////////////////////////////////////////
// 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"
struct SRP6A {
static constexpr char N3072[]="FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74"
"020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437"
"4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05"
@ -64,7 +66,8 @@ const char N3072[]="FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67
"D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2"
"08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
struct SRP6A {
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)
@ -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 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)
};