Skip to content

Commit

Permalink
Refactoring random SetupPinCode generation into a method. (#36009)
Browse files Browse the repository at this point in the history
* Creating a Function to generate random Setup Pin codes and making sure that the generated pin code is valid

* Using generateRandomSetupPin function to generate random setup pin codes

* Integrating comments

* Handling return value of generateRandomSetupPin invocation

Co-authored-by: Andrei Litvin <[email protected]>

* Integrating comments

---------

Co-authored-by: Andrei Litvin <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Oct 11, 2024
1 parent d49654b commit 9690532
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
5 changes: 1 addition & 4 deletions src/protocols/secure_channel/PASESession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,7 @@ CHIP_ERROR PASESession::GeneratePASEVerifier(Spake2pVerifier & verifier, uint32_

if (useRandomPIN)
{
ReturnErrorOnFailure(DRBG_get_bytes(reinterpret_cast<uint8_t *>(&setupPINCode), sizeof(setupPINCode)));

// Passcodes shall be restricted to the values 00000001 to 99999998 in decimal, see 5.1.1.6
setupPINCode = (setupPINCode % kSetupPINCodeMaximumValue) + 1;
ReturnErrorOnFailure(SetupPayload::generateRandomSetupPin(setupPINCode));
}

return verifier.Generate(pbkdf2IterCount, salt, setupPINCode);
Expand Down
29 changes: 29 additions & 0 deletions src/setup_payload/SetupPayload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "SetupPayload.h"

#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPVendorIdentifiers.hpp>
#include <lib/core/TLV.h>
Expand Down Expand Up @@ -207,6 +208,34 @@ CHIP_ERROR SetupPayload::removeSerialNumber()
return CHIP_NO_ERROR;
}

CHIP_ERROR SetupPayload::generateRandomSetupPin(uint32_t & setupPINCode)
{
uint8_t retries = 0;
const uint8_t maxRetries = 10;

do
{
ReturnErrorOnFailure(Crypto::DRBG_get_bytes(reinterpret_cast<uint8_t *>(&setupPINCode), sizeof(setupPINCode)));

// Passcodes shall be restricted to the values 00000001 to 99999998 in decimal, see 5.1.1.6
// TODO: Consider revising this method to ensure uniform distribution of setup PIN codes
setupPINCode = (setupPINCode % kSetupPINCodeMaximumValue) + 1;

// Make sure that the Generated Setup Pin code is not one of the invalid passcodes/pin codes defined in the
// specification.
if (IsValidSetupPIN(setupPINCode))
{
return CHIP_NO_ERROR;
}

retries++;
// We got pretty unlucky with the random number generator, Just try again.
// This shouldn't take many retries assuming DRBG_get_bytes is not broken.
} while (retries < maxRetries);

return CHIP_ERROR_INTERNAL;
}

CHIP_ERROR SetupPayload::addOptionalVendorData(const OptionalQRCodeInfo & info)
{
VerifyOrReturnError(IsVendorTag(info.tag), CHIP_ERROR_INVALID_ARGUMENT);
Expand Down
11 changes: 11 additions & 0 deletions src/setup_payload/SetupPayload.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,17 @@ class SetupPayload : public PayloadContents
**/
static bool IsVendorTag(uint8_t tag) { return !IsCommonTag(tag); }

/** @brief Generate a Random Setup Pin Code (Passcode)
*
* This function generates a random passcode within the defined limits (00000001 to 99999998)
* It also checks that the generated passcode is not equal to any invalid passcode values as defined in 5.1.7.1.
*
* @param[out] setupPINCode The generated random setup PIN code.
* @return Returns a CHIP_ERROR_INTERNAL if unable to generate a valid passcode within a reasonable number of attempts,
* CHIP_NO_ERROR otherwise
**/
static CHIP_ERROR generateRandomSetupPin(uint32_t & setupPINCode);

private:
std::map<uint8_t, OptionalQRCodeInfo> optionalVendorData;
std::map<uint8_t, OptionalQRCodeInfoExtension> optionalExtensionData;
Expand Down

0 comments on commit 9690532

Please sign in to comment.