From 98a3804828326c2f4b5b0594284a414351441028 Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Tue, 15 Nov 2022 19:37:37 +0800 Subject: [PATCH 1/4] spake2: generate verifier sets with specific PIN codes in a file --- src/tools/spake2p/Cmd_GenVerifier.cpp | 45 +++++++++++++++++++++++++-- src/tools/spake2p/README.md | 8 +++++ 2 files changed, 51 insertions(+), 2 deletions(-) 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. From ef7a77fd103d414a1267717feea4d3c346cd0d98 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Tue, 15 Nov 2022 11:50:36 +0000 Subject: [PATCH 2/4] Restyled by clang-format --- src/tools/spake2p/Cmd_GenVerifier.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/tools/spake2p/Cmd_GenVerifier.cpp b/src/tools/spake2p/Cmd_GenVerifier.cpp index 167e8ae7d5f7bd..1f7f3ea61848bc 100644 --- a/src/tools/spake2p/Cmd_GenVerifier.cpp +++ b/src/tools/spake2p/Cmd_GenVerifier.cpp @@ -149,20 +149,21 @@ 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; +FILE * gPinCodeFile = nullptr; static uint32_t GetNextPinCode() { - if (!gPinCodeFile) { + if (!gPinCodeFile) + { return chip::kSetupPINCodeUndefinedValue; } - char pinCodeStr[9] = {0}; + 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) + 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; } From ef5508a4fba2ab6ba2404f3a4aa4e4cee3632aa6 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Tue, 15 Nov 2022 11:50:41 +0000 Subject: [PATCH 3/4] Restyled by prettier-markdown --- src/tools/spake2p/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/spake2p/README.md b/src/tools/spake2p/README.md index a7dd96d3b6564c..61e6cb5748a12e 100644 --- a/src/tools/spake2p/README.md +++ b/src/tools/spake2p/README.md @@ -32,10 +32,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): +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. From d2183450b4d0447f1cd5ea91ab733ca1787084ff Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Wed, 16 Nov 2022 11:09:55 +0800 Subject: [PATCH 4/4] reviewing changes --- src/tools/spake2p/Cmd_GenVerifier.cpp | 42 +++++++++++++++++---------- src/tools/spake2p/README.md | 5 ++-- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/tools/spake2p/Cmd_GenVerifier.cpp b/src/tools/spake2p/Cmd_GenVerifier.cpp index 1f7f3ea61848bc..04bfe995a91ead 100644 --- a/src/tools/spake2p/Cmd_GenVerifier.cpp +++ b/src/tools/spake2p/Cmd_GenVerifier.cpp @@ -30,6 +30,7 @@ #include "spake2p.h" #include +#include #include #include @@ -89,7 +90,16 @@ const char * const gCmdOptionHelp = " -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" + " Each line in this file should be a valid PIN code in the decimal number format. If the row count\n" + " of this file is less than the number of pin-code/verifier parameter sets to be generated, the\n" + " first few verifier sets will be generated using the PIN codes in this file, and the next will\n" + " use the random PIN codes.\n" + " The following file is a example with 5 PIN codes:\n" + " 1234\n" + " 2345\n" + " 3456\n" + " 4567\n" + " 5678\n" "\n" " -i, --iteration-count \n" "\n" @@ -157,19 +167,24 @@ static uint32_t GetNextPinCode() { return chip::kSetupPINCodeUndefinedValue; } - char pinCodeStr[9] = { 0 }; - if (fgets(pinCodeStr, 8, gPinCodeFile) != nullptr) + char * pinCodeStr = nullptr; + size_t readSize = 8; + uint32_t pinCode = chip::kSetupPINCodeUndefinedValue; + if (getline(&pinCodeStr, &readSize, gPinCodeFile) != -1) { - 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) + if (readSize > 8) { - return chip::kSetupPINCodeUndefinedValue; + pinCodeStr[8] = 0; } - return pinCode; + pinCode = static_cast(atoi(pinCodeStr)); + if (!chip::SetupPayload::IsValidSetupPIN(pinCode)) + { + fprintf(stderr, "The line %s in PIN codes file is invalid, using a random PIN code.\n", pinCodeStr); + pinCode = chip::kSetupPINCodeUndefinedValue; + } + free(pinCodeStr); } - return chip::kSetupPINCodeUndefinedValue; + return pinCode; } bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg) @@ -185,11 +200,7 @@ bool HandleOption(const char * progName, OptionSet * optSet, int id, const char break; case 'p': // Specifications sections 5.1.1.6 and 5.1.6.1 - if (!ParseInt(arg, gPinCode) || (gPinCode > chip::kSetupPINCodeMaximumValue) || - (gPinCode == chip::kSetupPINCodeUndefinedValue) || (gPinCode == 11111111) || (gPinCode == 22222222) || - (gPinCode == 33333333) || (gPinCode == 44444444) || (gPinCode == 55555555) || (gPinCode == 66666666) || - (gPinCode == 77777777) || (gPinCode == 88888888) || (gPinCode == 99999999) || (gPinCode == 12345678) || - (gPinCode == 87654321)) + if (!ParseInt(arg, gPinCode) || (!chip::SetupPayload::IsValidSetupPIN(gPinCode))) { PrintArgError("%s: Invalid value specified for pin-code parameter: %s\n", progName, arg); return false; @@ -372,6 +383,7 @@ bool Cmd_GenVerifier(int argc, char * argv[]) return false; } + // If the file with PIN codes is not provided, the PIN code on next iteration will be randomly generated. gPinCode = GetNextPinCode(); // On the next iteration the Salt will be randomly generated. gSaltDecodedLen = 0; diff --git a/src/tools/spake2p/README.md b/src/tools/spake2p/README.md index 61e6cb5748a12e..d6cb3da681fd78 100644 --- a/src/tools/spake2p/README.md +++ b/src/tools/spake2p/README.md @@ -36,7 +36,8 @@ 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 +./spake2p gen-verifier --count 100 --pin-code-file pincodes.csv --iteration-count 15000 --salt-len 32 --out spake2p-provisioning-data.csv ``` -Notes: Each line of the `pincodes.txt` should be a valid PIN code. +Notes: Each line of the `pincodes.csv` should be a valid PIN code. You can use +`spake2p --help` to get the example content of the file.