diff --git a/src/tools/spake2p/Cmd_GenVerifier.cpp b/src/tools/spake2p/Cmd_GenVerifier.cpp index 959c4d354de4a7..167e8ae7d5f7bd 100644 --- a/src/tools/spake2p/Cmd_GenVerifier.cpp +++ b/src/tools/spake2p/Cmd_GenVerifier.cpp @@ -52,6 +52,7 @@ OptionDef gCmdOptionDefs[] = { { "count", kArgumentRequired, 'c' }, { "pin-code", kArgumentRequired, 'p' }, + { "pin-code-file", kArgumentRequired, 'f' }, { "iteration-count", kArgumentRequired, 'i' }, { "salt-len", kArgumentRequired, 'l' }, { "salt", kArgumentRequired, 's' }, @@ -85,6 +86,11 @@ const char * const gCmdOptionHelp = " * 12345678\n" " * 87654321\n" "\n" + " -f, --pin-code-file \n" + "\n" + " A file which contains all the PIN codes to generate verifiers.\n" + " Each line in this file should be a valid PIN code.\n" + "\n" " -i, --iteration-count \n" "\n" " SPAKE2P PBKDF iteration count. The value should be positive integer in range [1000..100000].\n" @@ -143,6 +149,27 @@ uint8_t gSalt[BASE64_MAX_DECODED_LEN(BASE64_ENCODED_LEN(chip::kSpake2p_Max_PBKDF uint8_t gSaltDecodedLen = 0; uint8_t gSaltLen = 0; const char * gOutFileName = nullptr; +FILE *gPinCodeFile = nullptr; + +static uint32_t GetNextPinCode() +{ + if (!gPinCodeFile) { + return chip::kSetupPINCodeUndefinedValue; + } + char pinCodeStr[9] = {0}; + if (fgets(pinCodeStr, 8, gPinCodeFile) != nullptr) + { + uint32_t pinCode = atoi(pinCodeStr); + if (pinCode == 11111111 || pinCode == 22222222 || pinCode == 33333333 || pinCode == 44444444 || + pinCode == 55555555 || pinCode == 66666666 || pinCode == 77777777 || pinCode == 88888888 || + pinCode == 99999999 || pinCode == 12345678 || pinCode == 87654321) + { + return chip::kSetupPINCodeUndefinedValue; + } + return pinCode; + } + return chip::kSetupPINCodeUndefinedValue; +} bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg) { @@ -168,6 +195,16 @@ bool HandleOption(const char * progName, OptionSet * optSet, int id, const char } break; + case 'f': + gPinCodeFile = fopen(arg, "r"); + if (!gPinCodeFile) + { + PrintArgError("%s: Failed to open the PIN code file: %s\n", progName, arg); + return false; + } + gPinCode = GetNextPinCode(); + break; + case 'i': if (!ParseInt(arg, gIterationCount) || !(gIterationCount >= chip::kSpake2p_Min_PBKDF_Iterations && gIterationCount <= chip::kSpake2p_Max_PBKDF_Iterations)) @@ -334,10 +371,14 @@ bool Cmd_GenVerifier(int argc, char * argv[]) return false; } - // On the next iteration the PIN Code and Salt will be randomly generated. - gPinCode = chip::kSetupPINCodeUndefinedValue; + gPinCode = GetNextPinCode(); + // On the next iteration the Salt will be randomly generated. gSaltDecodedLen = 0; } + if (gPinCodeFile) + { + fclose(gPinCodeFile); + } return true; } diff --git a/src/tools/spake2p/README.md b/src/tools/spake2p/README.md index b895f1284bfa40..a7dd96d3b6564c 100644 --- a/src/tools/spake2p/README.md +++ b/src/tools/spake2p/README.md @@ -31,3 +31,11 @@ random Salts and corresponding Verifiers): ``` ./spake2p gen-verifier --count 100 --iteration-count 15000 --salt-len 32 --out spake2p-provisioning-data.csv ``` + +Example command that generates 100 sets of spake2p parameters (Specific PIN Codes, +random Salts and corresponding Verifiers): + +``` +./spake2p gen-verifier --count 100 --pin-code-file pincodes.txt --iteration-count 15000 --salt-len 32 --out spake2p-provisioning-data.csv +``` +Notes: Each line of the `pincodes.txt` should be a valid PIN code.